2017-03-23 1 views
0

파이썬 3.6에서 다중 스레드 TCP Echo 서버를 만들었습니다. 메시지를 보내려고 할 때까지 모든 것이 잘 작동합니다 (서버에 메시지를 보내고 다시 에코 할 수 있습니다). 수신되지 않은 두 번째 클라이언트와 함께 보내고 두 번째 클라이언트에게 BrokenPipe 오류를 보냅니다. 사이트에서 살펴 보았지만 파이썬 2.7에 대한 해결책을 찾았으며 스레딩 모듈 설명서에서 찾지 못한 ThreadingMixIn 함수에 대해 언급했습니다. 나는 문제가 Client_Handler.join (에 의해 차단 될 수 있습니다) 그래서이 두 번째 클라이언트의 새 값을 저장할 수 없습니다하지만 난 '는 client_socket 것 같아요Python 3.6 하나 이상의 클라이언트에 대한 다중 스레드 TCP Echo 서버

#!/usr/bin/env python3 

import socket,sys,threading 

def accept_connection(tcp_socket): 
    (client_socket,(ip,port))=tcp_socket.accept() 
    print("Accepted connection from %s on port %d"%(ip,port)) 
    return (client_socket,ip,port) 

def client_action(client_socket,ip,port): 
    data=client_socket.recv(2048) 
    print("Sending back: %s to %s on %d"%(data.decode(),ip,port)) 
    client_socket.send(data) 

tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
tcp_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 
tcp_socket.bind((sys.argv[1],int(sys.argv[2]))) 
tcp_socket.listen(2) 

print("Listening incoming connections...") 
(client_socket,ip,port)=accept_connection(tcp_socket) 

while True: 
    Connections_Handler=threading.Thread(target=accept_connection,args=(tcp_socket,)) 
    Connections_Handler.start() 
    Client_Handler=threading.Thread(target=client_action,args=(client_socket,ip,port,)) 
    Client_Handler.start() 
    Client_Handler.join() 

이 내 서버 코드 모르겠다. 그렇다면 다시 두 개의 클라이언트가 서버에 "말하며"보내질 때 각각의 "에코 메시지"를받을 수 있기를 원했습니다. 이 내 클라이언트 코드 (둘 다)입니다 :

#!/usr/bin/env python3 

import socket,sys 

tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 
tcp_socket.connect((sys.argv[1],int(sys.argv[2]))) 

print("Connecting to server %s on port %d..."%(sys.argv[1],int(sys.argv[2]))) 

while True: 
    message=input("Input message to send: ") 
    tcp_socket.send(message.encode()) 
    print(tcp_socket.recv(2048).decode()) 

내가 잘못 여기서 뭐하는거야?

+0

[Python 3에서 변수/텍스트를 LAN으로 보내기/동기화] (http://stackoverflow.com/questions/30224933/send-sync-variable-text-over-lan-in-python-3)의 가능한 복제본 –

답변

0

중요한 디자인 문제가 있습니다. 클라이언트 소켓을 반환하는 하나의 스레드 (ConnectionsHandler)에서 연결을 수락합니다 ... 아무 것도 없습니다! 그런 다음 새로 승인 된 클라이언트 소켓과 관련이없는 클라이언트 소켓에 데이터를 반향시키기위한 두 번째 스레드를 시작합니다.

주 스레드에서 호출을 수락하고 데이터를 에코하려면 새 스레드를 시작해야합니다. 아무리 나쁜 소켓이라도 절대로 닫을 수 없습니다.

허용 된 소켓을 올바르게 사용하는 올바른 스레드 프로그램을 작성하고 멀티 스레드를 시도하기 전에 닫으면 올바르게 종료하십시오.

+0

내가 무슨 말을하는지 ... Connections_Handler를 만들 때 대상 함수의 반환 값을 저장할 수 있습니까? –

+0

나는 그것을 알아 냈다, 나는 큐를 사용했고 모든 것이 이제는 괜찮다. 올바른 방향을 가리켜 주셔서 감사합니다. –

관련 문제