간단한 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