Многопоточный эхо-сервер 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), которое возвращает клиентский сокет в... ничего! Затем вы запускаете второй поток для вывода данных на клиентском сокете, не связанном с недавно принятым.

Вы должны принять вызов в главном потоке, а затем начать новый поток для отображения данных. Кстати, вы никогда не закрываете сокет, что плохо.

Пожалуйста, напишите правильную однопоточную правильную программу, которая правильно использует принятый сокет и закрывает его, когда завершает работу, прежде чем пытаться его многопоточить.

Другие вопросы по тегам