Created
April 4, 2015 20:38
-
-
Save loadletter/a8604e933e9c77cb8bea to your computer and use it in GitHub Desktop.
ThreadedUDPServer with threadpool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Threaded UDPServer with threadpool | |
import SocketServer | |
from Queue import Queue | |
import threading, socket | |
class ThreadPoolMixIn(SocketServer.ThreadingMixIn): | |
''' | |
use a thread pool instead of a new thread on every request | |
''' | |
numThreads = 10 | |
allow_reuse_address = True | |
def serve_forever(self): | |
''' | |
Handle one request at a time until doomsday. | |
''' | |
# set up the threadpool | |
self.requests = Queue(self.numThreads) | |
for x in range(self.numThreads): | |
t = threading.Thread(target = self.process_request_thread) | |
t.setDaemon(1) | |
t.start() | |
# server main loop | |
while True: | |
self.handle_request() | |
self.server_close() | |
def process_request_thread(self): | |
''' | |
obtain request from queue instead of directly from server socket | |
''' | |
while True: | |
SocketServer.ThreadingMixIn.process_request_thread(self, *self.requests.get()) | |
def handle_request(self): | |
''' | |
simply collect requests and put them on the queue for the workers. | |
''' | |
try: | |
request, client_address = self.get_request() | |
except socket.error: | |
return | |
if self.verify_request(request, client_address): | |
self.requests.put((request, client_address)) | |
class ThreadedUDPRequestHandler(SocketServer.BaseRequestHandler): | |
def handle(self): | |
data = self.request[0].strip() | |
### get port number | |
port = self.client_address[1] | |
### get the communicate socket | |
socket = self.request[1] | |
### get client host ip address | |
client_address = (self.client_address[0]) | |
### proof of multithread | |
cur_thread = threading.current_thread() | |
print "thread %s" %cur_thread.name | |
print "received call from client address :%s" %client_address | |
print "received data from port [%s]: %s" %(port,data) | |
### assemble a response message to client | |
response = "%s %s"%(cur_thread.name, data) | |
socket.sendto(data.upper(), self.client_address) | |
class ThreadPoolUDPServer(ThreadPoolMixIn, SocketServer.UDPServer): | |
pass | |
if __name__ == '__main__': | |
HOST, PORT = "localhost", 8888 | |
server = ThreadPoolUDPServer((HOST, PORT), ThreadedUDPRequestHandler) | |
ip, port = server.server_address | |
server.serve_forever() | |
# Start a thread with the server -- | |
# that thread will then start one | |
# more thread for each request | |
server_thread = threading.Thread(target=server.serve_forever) | |
# Exit the server thread when the main thread terminates | |
server_thread.daemon = True | |
server_thread.start() | |
server.shutdown() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment