[Python] Thread, Socket을 이용한 간단한 채팅 프로그램 구현

2011. 5. 28. 02:11
한 언어를 배울 때, 책상 앞에 앉아 책만 보기보다는 뭔가 작은 프로그램을 직접 만들어보는 것이 진리. 간단한 파이썬을 이용하여 간단한 채팅 프로그램을 구현해보기로 했다. TCP/IP 소켓 통신 관련하여 검색해보니 간단한 예제들이 수도 없이 나왔다. 물론 대부분이 2.x 버전에서 구현된 것들이다. http://www.python.org/에서  3.2 버전의 socket을 검색하니 간단하게 참고할만한 예제가 있었다. 하지만 서버에서 응답 한번 해주고 바로 소켓을 닫아버리는 소스이기에 이것을 좀 수정해서 계속해서 여러 메시지를 주거니 받거니 할 수 있도록 만들고 싶었다.

#client program
import socket
import threading

HOST = "127.0.0.1"
PORT = 8089      
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))


def sendingMsg():
	while True:
		data = input()
		data = bytes(data, "utf-8")
		s.send(data)
	s.close()
	
def gettingMsg():
	while True:
		data = s.recv(1024)
		data = str(data).split("b'", 1)[1].rsplit("'",1)[0]
		print(data)
	s.close()

threading._start_new_thread(sendingMsg,())
threading._start_new_thread(gettingMsg,())

while True:
	pass

#server program
import socket
import threading

HOST = ''                
PORT = 8089        
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)

def sendingMsg():
	while True:
		data = input()
		data = data.encode("utf-8")
		conn.send(data)
	conn.close()

def gettingMsg():
	while True:
		data = conn.recv(1024)
		if not data: 
			break
		else:
			data = str(data).split("b'", 1)[1].rsplit("'",1)[0]
			print(data)
	conn.close()
	
threading._start_new_thread(sendingMsg,())
threading._start_new_thread(gettingMsg,())

while True:
	pass

파이썬3에서는 그냥 메시지를 전달하면 str는 지원하지 않는다는 에러메시지가 나온다. 그래서 이를 bytes형으로 변환하기 위해 encode함수를 이용하였다. 그러니 메시지 앞에 byte라는 의미의 b가 달라붙어버렸다. (hello -> b'hello') 이를 해결하기 위해 일단은 문자열 변환으로 b와 ' ' 를 지워서 출력하기는 했는데 str함수로 형변환 했을 때 깔끔하게 b를 지워줬으면 좋겠다. 분명히 문자열 변환같은 수동적인 방법말고 뭔가 다른 방법이 있을 것 같긴 한데...

마지막에 While True: pass 도 엄청난 삽질 끝에 삽입하였다. Thread를 이용해서 함수를 시작시키도록 코드를 구현한 뒤 파일을 실행했는데 아무런 반응이 없었다. 이 이유를 몰라서 한참 삽질하다보니 쓰레드로 특정 함수를 시작하자마자 코드의 마지막을 읽음으로서 파일 실행이 끝나버리는 ... 그렇다, 파이썬은 스크립트언어다. 인터프리터 방식의.... 그래서 프로그램이 끝나지 않고 계속 쓰레드가 돌아갈 수 있도록 의미없이 무한반복하는 코드를 집어넣었다. 아휴, 파이썬의 길은 멀고도 험하구나~

박상근 프로그래밍/Python