multithreadingpython-3.xtcpecho-server

Python 3.6 Multithread TCP Echo Server for more than one client


I've made a multithread TCP Echo Server in python 3.6, everything works fine (i can send message to the server and echo them back) until i try to send a message with a second client which is not received and if i try to send a second one gives me the BrokenPipe error. I've looked around here on the site but all i found was solutions for python 2.7 and mentions to a ThreadingMixIn function which i didn't found on the threading module documentation. This is my server code:

#!/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()

I think the problem might be the client_socket which might be being blocked by the Client_Handler.join() and so it can't save the new values of the second client but i'm not sure. Then again i wanted to be possible to have the two clients "talking" to the server and receiving their respectively "echo message" when sent. This is my clients code (both of them):

#!/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())

What i'm doing wrong here?


Solution

  • You have a major design issue: you accept a connection in one thread (ConnectionsHandler) that returns the client socket to... nothing! Then you start a second thread to echo data on a client socket unrelated to the newly accepted one.

    You should accept a call in main thread, and then start a new thread to echo data. BTW you never close any socket which is bad.

    Please write a single threaded correct program that correctly uses the accepted socket and closes it when done before trying to multithread it.