Многопоточный эхо-сервер Python 3.6 для нескольких клиентов
Я сделал многопоточный TCP Echo Server в Python 3.6, все работает нормально (я могу отправить сообщение на сервер и отправить их обратно), пока я не попытаюсь отправить сообщение вторым клиентом, который не получен, и если я попытаюсь отправить второй дает мне ошибку BrokenPipe. Я посмотрел здесь на сайте, но все, что я нашел, это решения для python 2.7 и упоминание о функции ThreadingMixIn, которую я не нашел в документации модуля потоков. Это мой код сервера:
#!/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()
Я думаю, что проблема может быть в client_socket, который может быть заблокирован 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())
Что я здесь не так делаю?
1 ответ
У вас есть серьезная проблема проектирования: вы принимаете соединение в одном потоке (ConnectionsHandler), которое возвращает клиентский сокет в... ничего! Затем вы запускаете второй поток для вывода данных на клиентском сокете, не связанном с недавно принятым.
Вы должны принять вызов в главном потоке, а затем начать новый поток для отображения данных. Кстати, вы никогда не закрываете сокет, что плохо.
Пожалуйста, напишите правильную однопоточную правильную программу, которая правильно использует принятый сокет и закрывает его, когда завершает работу, прежде чем пытаться его многопоточить.