Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 소켓 프로그래밍으로 만드는 간단한 채팅방 시스템

이 글에서는 파이썬(Python)의 소켓 프로그래밍(Socket Programming)을 활용하여 서버와 클라이언트로 구성된 간단한 채팅방 시스템을 만드는 방법을 알아봅니다.

소켓(Socket)이란 무엇인가?

소켓은 모든 통신 채널의 양 끝단(endpoint)을 의미합니다. 서버와 클라이언트를 연결하는 역할을 하며, 데이터가 양방향으로 오갈 수 있도록 지원합니다.

소켓은 기본적으로 양방향(Bi-Directional) 통신을 제공하기 때문에, 각 끝단에 소켓을 설정하고 서버를 중심으로 여러 클라이언트 간의 채팅 시스템을 구축할 수 있습니다. 서버 측에는 클라이언트 소켓이 접속할 수 있는 포트(port)가 마련되어 있으며, 클라이언트가 동일한 포트로 접속을 시도하면 연결이 성립되어 채팅방이 열리게 됩니다.

시스템 구조 이해하기

전체 시스템은 크게 두 부분으로 나뉩니다.

  • 서버 측(Server Side): 스크립트를 실행하면 접속 요청이 들어올 때까지 대기하며, 연결이 성립되면 해당 클라이언트와 메시지를 주고받습니다.
  • 클라이언트 측(Client Side): 서버의 IP 주소와 포트 번호를 지정하여 서버에 접속한 뒤 대화를 시작합니다.

이번 예제에서는 localhost(로컬 환경)를 기준으로 설명하지만, 여러 대의 컴퓨터가 LAN으로 연결되어 있다면 실제 IP 주소를 사용해 서로 통신할 수도 있습니다. 서버는 실행 시 자신의 IP 주소를 화면에 표시하고 서버 이름을 입력받으며, 클라이언트 측에서는 자신의 이름과 함께 접속할 서버의 IP 주소를 입력해야 합니다.

서버 측 코드

import time, socket, sys

print('Setup Server...')
time.sleep(1)

# 호스트명과 IP 주소를 가져오고 포트를 설정
soc = socket.socket()
host_name = socket.gethostname()
ip = socket.gethostbyname(host_name)
port = 1234
soc.bind((host_name, port))
print(host_name, '({})'.format(ip))

name = input('Enter name: ')
soc.listen(1)  # 소켓을 통해 접속 대기
print('Waiting for incoming connections...')

connection, addr = soc.accept()
print("Received connection from ", addr[0], "(", addr[1], ")\n")
print('Connection Established. Connected From: {}, ({})'.format(addr[0], addr[0]))

# 클라이언트로부터 연결 받기
client_name = connection.recv(1024)
client_name = client_name.decode()
print(client_name + ' has connected.')
print('Press [bye] to leave the chat room')
connection.send(name.encode())

while True:
    message = input('Me > ')
    if message == '[bye]':
        message = 'Good Night...'
        connection.send(message.encode())
        print("\n")
        break
    connection.send(message.encode())
    message = connection.recv(1024)
    message = message.decode()
    print(client_name, '>', message)

서버 코드 핵심 흐름

  1. socket.socket()으로 소켓 객체를 생성합니다.
  2. socket.gethostname()socket.gethostbyname()으로 호스트명과 IP 주소를 확인합니다.
  3. soc.bind()로 포트(1234)를 바인딩한 뒤, soc.listen(1)로 접속을 대기합니다.
  4. soc.accept()로 클라이언트의 연결을 수락하고, 상대방 이름을 주고받습니다.
  5. while True 반복문 안에서 메시지를 주고받으며, [bye]를 입력하면 종료 메시지를 전송하고 채팅을 마칩니다.

클라이언트 측 코드

import time, socket, sys

print('Client Server...')
time.sleep(1)

# 호스트명과 IP 주소 확인
soc = socket.socket()
shost = socket.gethostname()
ip = socket.gethostbyname(shost)
print(shost, '({})'.format(ip))

# 서버 접속 정보 입력
server_host = input('Enter server\'s IP address:')
name = input('Enter Client\'s name: ')
port = 1234

print('Trying to connect to the server: {}, ({})'.format(server_host, port))
time.sleep(1)
soc.connect((server_host, port))
print("Connected...\n")

soc.send(name.encode())
server_name = soc.recv(1024)
server_name = server_name.decode()
print('{} has joined...'.format(server_name))
print('Enter [bye] to exit.')

while True:
    message = soc.recv(1024)
    message = message.decode()
    print(server_name, ">", message)
    message = input(str("Me > "))
    if message == "[bye]":
        message = "Leaving the Chat room"
        soc.send(message.encode())
        print("\n")
        break
    soc.send(message.encode())

클라이언트 코드 핵심 흐름

  1. 소켓을 생성하고 자신의 호스트 정보를 출력합니다.
  2. 접속할 서버의 IP 주소와 자신의 이름을 입력받습니다.
  3. soc.connect()로 서버(포트 1234)에 접속을 시도합니다.
  4. 연결 성공 후 서버와 이름을 교환하고 채팅을 시작합니다.
  5. 서버가 보낸 메시지를 먼저 수신하고, 본인의 메시지를 입력해 전송합니다. [bye] 입력 시 퇴장 메시지를 보내고 종료합니다.

실행 방법 및 참고 사항

먼저 서버 스크립트를 실행한 뒤, 새 터미널(또는 다른 PC)에서 클라이언트 스크립트를 실행하세요. 클라이언트가 서버의 IP 주소로 접속하면 두 프로그램의 콘솔 창에서 실시간으로 메시지를 주고받을 수 있습니다.

참고로 이 예제는 하나의 클라이언트와 1:1로 통신하는 가장 기본적인 형태입니다. 여러 명이 동시에 접속하는 채팅방을 만들려면 스레딩(threading)을 활용해 다중 클라이언트 연결을 처리하도록 확장할 수 있습니다. 또한 실습 후에는 방화벽 설정이나 포트 충돌 여부도 함께 확인하시기 바랍니다.