python tcp 소켓 프로그래밍
2017. 4. 30. 17:23
간단한 server 와 client 구성
에코 프로그램
server
import socket
HOST=''
PORT=12345
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr=s.accept()
print('Connected by',addr)
while True:
data=conn.recv(1024)
if not data: break
conn.send(data)
conn.close()
socket -> bind -> listen -> accept -> client의 connect 후 -> recv
s.listen(NUM) : NUM은 queue의 수를 의미
conn.recv(NUM): NUM은 버퍼에서 읽을 크기를 의미
recv 한 data와 send에 보내는 data는 byte-like obejct
client
import socket
HOST='127.0.0.1'
PORT=12345
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((HOST,PORT))
x=input("hello: ")
s.send(x.encode('utf-8'))
data=s.recv(1024)
s.close()
print('Received',data.decode('utf-8'))
# print('Received',data.decode('EUC-KR'))
# print('Received',data)
x.encode()는 str의 x를 bytearray로 바꿔줌, 기본이 utf-8 인듯
echo 로 돌아온 data를 utf-8로 디코드 해 주어야 정상적인 값 얻을 수 있음
EUC-KR은 decode 불가능으로 에러나는 것을 볼 수 있음
"EUC-KR","ignore"사용하면 에러는 안나는데 깨져서 출력되는 것을 볼 수 있음,
data를 그대로 출력하면 byte sequence를 볼 수 있음.
채팅 프로그램
server는
recv + print, send 반복
client는
send, recv + print 반복
문제점: 서로 한마디씩 밖에 못함..
-> 해결: thred이용
server
#server program
import socket
import threading
HOST = ''
PORT = 12345
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 send_Msg():
while True:
data = input()
data = data.encode("utf-8")
conn.send(data)
conn.close()
def recv_Msg():
while True:
data = conn.recv(1024)
if not data:
break
else:
data = data.decode("utf-8")
print(data)
conn.close()
#threading._start_new_thread(send_Msg,())
#threading._start_new_thread(recv_Msg,())
threading.Thread(target=send_Msg).start()
threading.Thread(target=recv_Msg).start()
client
#client program
import socket
import threading
HOST = "127.0.0.1"
PORT = 12345
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
def send_Msg():
while True:
data = input()
data = data.encode("utf-8")
s.send(data)
s.close()
def recv_Msg():
while True:
data = s.recv(1024)
data = data.decode("utf-8")
print(data)
s.close()
#threading._start_new_thread(send_Msg,())
#threading._start_new_thread(recv_Msg,())
threading.Thread(target=send_Msg).start()
threading.Thread(target=recv_Msg).start()
그러나 위와같이 실행하면 바로 끝남
threading._start_new_thread()이 원인인 것으로 추정
아마도 main프로그램이 끝나면 thread도 같이 끝내는 것으로 판단.
위의 threading._start_new_thread(send_Msg,()) 대신
앞의 크롤링 예제의 맨 마지막 처럼
threading.Thread(target=send_Msg).start()
을 사용하면 메인프로그램이 끝나도 계속 유지됨
--->
http://stackoverflow.com/questions/5882362/thread-start-new-thread-vs-threading-thread-start
참고
응용: 채팅이 아닌 명령어를 통해 서버에서 명령어를 받으면 그에 맞는 파일을 반환하는 것으로 응용가능
참조: https://docs.python.org/3/library/socket.html