이 글에서는 파이썬(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)서버 코드 핵심 흐름
socket.socket()으로 소켓 객체를 생성합니다.socket.gethostname()과socket.gethostbyname()으로 호스트명과 IP 주소를 확인합니다.soc.bind()로 포트(1234)를 바인딩한 뒤,soc.listen(1)로 접속을 대기합니다.soc.accept()로 클라이언트의 연결을 수락하고, 상대방 이름을 주고받습니다.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())클라이언트 코드 핵심 흐름
- 소켓을 생성하고 자신의 호스트 정보를 출력합니다.
- 접속할 서버의 IP 주소와 자신의 이름을 입력받습니다.
soc.connect()로 서버(포트 1234)에 접속을 시도합니다.- 연결 성공 후 서버와 이름을 교환하고 채팅을 시작합니다.
- 서버가 보낸 메시지를 먼저 수신하고, 본인의 메시지를 입력해 전송합니다.
[bye]입력 시 퇴장 메시지를 보내고 종료합니다.
실행 방법 및 참고 사항
먼저 서버 스크립트를 실행한 뒤, 새 터미널(또는 다른 PC)에서 클라이언트 스크립트를 실행하세요. 클라이언트가 서버의 IP 주소로 접속하면 두 프로그램의 콘솔 창에서 실시간으로 메시지를 주고받을 수 있습니다.
참고로 이 예제는 하나의 클라이언트와 1:1로 통신하는 가장 기본적인 형태입니다. 여러 명이 동시에 접속하는 채팅방을 만들려면 스레딩(threading)을 활용해 다중 클라이언트 연결을 처리하도록 확장할 수 있습니다. 또한 실습 후에는 방화벽 설정이나 포트 충돌 여부도 함께 확인하시기 바랍니다.