Overview:
- Python’s ThreadingUDPServer enables creating multi-threaded UDP based network servers at ease.
- ThreadingUDPServer forms the base class of all UDP based multithreaded servers using the Python’s socketserver framework.
- ThreadingUDPServer is derived from the class ThreadingMixIn.
- Developers can choose to use an instance of ThreadingUDPServer if no customization of threading is needed beyond the implementation provided by the ThreadingMixIn.
- ThreadingUDPServer can further be sub-classed based on the requirements like thread pooling and other intricacies that may required for an UDP server.
Creation of a Multi-threaded UDP Server:
- A request handler instance needs to be created. In case of an UDP based network server the socketserver provided class DatagramRequestHandler needs to be sub-classed and the handle() method to be overridden.
- An instance of ThreadingUDPServer to be created by providing the below parameters:
- A tuple with IP address of the server and the port number at which the server will be listening
- Name of the request handler class – In this case the name of the sub-class derived from DatagramRequestHandler.
- Once an instance of the ThreadingUDPServer is created, the method to be called to make the server listen continuously for the incoming requests.
Example - Multi-threaded UDP Server using ThreadingUDPServer:
# Sample UDP Server - Multi threaded
# Import the necessary python modules import socketserver import threading
# Create a tuple with IP Address and Port Number ServerAddress = ("127.0.0.1", 5050)
# Subclass the DatagramRequestHandler class MyUDPRequestHandler(socketserver.DatagramRequestHandler):
# Override the handle() method def handle(self): # Receive and print the datagram received from client print("Recieved one request from {}".format(self.client_address[0])) datagram = self.rfile.readline().strip()
print("Datagram Recieved from client is:".format(datagram)) print(datagram)
# Print the name of the thread print("Thread Name:{}".format(threading.current_thread().name))
# Send a message to the client self.wfile.write("Message from Server! Hello Client".encode())
# Create a Server Instance UDPServerObject = socketserver.ThreadingUDPServer(ServerAddress, MyUDPRequestHandler)
# Make the server wait forever serving connections UDPServerObject.serve_forever() |
Example - Multi-threaded UDP Client using socket class:
#Sample UDP Client - Multi threaded
#import the socket module import socket
#import the threading module import threading
# Define the message to the server msgFromClient = "Hello UDP Server" bytesToSend = str.encode(msgFromClient)
# Buffer size for receiving the datagrams from server bufferSize = 1024
# Server IP address and Port number serverAddressPort = ("127.0.0.1", 5050)
# Connect2Server forms the thread - for each connection made to the server def Connect2Server(): #Create a socket instance - A datagram socket UDPClientSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
# Send message to server using created UDP socket UDPClientSocket.sendto(bytesToSend, serverAddressPort)
#Receive message from the server msgFromServer = UDPClientSocket.recvfrom(bufferSize) msg = "Message from Server {}".format(msgFromServer[0])
print(msg)
print("Client - Main thread started") ThreadList = [] ThreadCount = 20
# Create as many connections as defined by ThreadCount for index in range(ThreadCount): ThreadInstance = threading.Thread(target=Connect2Server()) ThreadList.append(ThreadInstance) ThreadInstance.start()
# Main thread to wait till all connection threads are complete for index in range(ThreadCount): ThreadList[index].join()
|
Output - Server:
Recieved one request from 127.0.0.1 Datagram Recieved from client is: b'Hello UDP Server' Thread Name:Thread-1 . . . Recieved one request from 127.0.0.1 Datagram Recieved from client is: b'Hello UDP Server' Thread Name:Thread-20 |
Output - Client:
Message from Server b'Message from Server! Hello Client' . . . Message from Server b'Message from Server! Hello Client' |