0

I am trying to implement UDP concurrent server (multi-threaded) which can accept new client and communicate with old client simultaneously. I have a main python program (called server) which creates a thread for every new accepted client and then loops back and wait for request from new client. The created thread deals with the respective client regarding upload, download and other tasks. The problem arises when two socket.recvfrom(1024) functions are called simultaneously, one in the main thread (where new clients are being accepted) and the other in the previously created thread where a function tries to receives data from the corresponding client. So, an UPD packet sent from a client, ends up in unexpected location as the function socket.recvfrom(1024) are running concurrently in two threads.

In my case, when a client which is already connected, tries to send data to the server for a function, the data which is supposed to be received by the corresponding thread of the server, is being received by the main program (main thread) which is supposed to receive new client request. So, the client get stuck there.

My code for the main program (main thread) and the function (which runs as a separate thread) is given below:

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, PORT))

def ClientHandler(addr):
    while True:
        str = "Select an option from below:\n 1. Upload\n 2. Download"
        sock.sendto(str.encode(), addr)
        data, addr = sock.recvfrom(1024) #receiver 2 running in parallel thread  
        if(data.decode()=="Upload" or data.decode()=="upload"):
            ReceiveFile() #receive a file from the client
        elif(data.decode()=="Download" or data.decode()=="download"):
            SendFile() #send a file to the client

while True:
        print("\nListening...\n")
        data, addr = sock.recvfrom(1024) #receiver 1 running in main thread
        if(data.decode()=="Hello"): #Using the Hello keyword to detect new client
            print("Connected to a New Client " + str(addr))
            t1=threading.Thread(target=ClientHandler, args=(addr,))
            t1.start()
  • If you want to use the current pattern of one thread per client then you need a __connected__ socket per client. A UDP socket gets connected by calling `connect` on it with the peer addr - in which case it will only get data from this specific peer and can only send to this one. But it might actually be easier to have a single thread and single socket, which handles recv and send for all peers. – Steffen Ullrich Feb 03 '23 at 18:41
  • Thank you for giving me an useful insight. As for UDP, it is connectionless, so it cannot use the connect function like tcp. But now I am trying to assign each client an unique port number and hence do all future communication through the port. Will let u know if it works! – Md. Kamrul Hossain Feb 03 '23 at 19:29
  • *"it cannot use the connect function like tcp"* - it can. `connect` in UDP will not actually initiate a connection like in TCP but it just sets the peer address on the UDP socket so that it will only receive data from this peer and only send data to this peer. And a connected UDP socket will take preference when receiving data over an unconnected UDP socket bound to the same local address – Steffen Ullrich Feb 03 '23 at 19:57
  • Ah! That's great to know! Will definitely try. – Md. Kamrul Hossain Feb 04 '23 at 07:29

0 Answers0