Reputation: 24721
I am new to python. And I have to write a listener/server which will handle requests coming from same network. So I am using socket
. I will be getting request json from client, server/listener will do processing and return the result. Thats all what is going to happen. And there will be no back and forth communication between server and client.
The code looks something like this:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 10000)
sock.bind(server_address)
sock.listen(1)
while True:
connection, client_address = sock.accept()
while True:
#read request data
#process request
#reply response to **connection** object
break #continue waiting for new request
Now the issue is that until the current request's processing is done, server will not accept new request. I somehow have to perform processing and sending response reply in separate concurrent thread. I tried by encapsulating the processing logic in separate class RequestHandler
extending the Thread
class. I passed connection
object to the instance of my custom class RequestHandler
.
I did something like this:
requestHandler = RequestHandler(deepcopy(connection))
requestHandler.daemon = True
requestHandler.start()
However here is where I have stuck. Can I pass same connection
object to new instances RequestHandler
spawned each time I receive new request? Deep copying as in above code gave me following error:
TypeError: Cannot serialize socket object
I am doing something absolutely wrong? Should I follow some different approach?
Upvotes: 1
Views: 976
Reputation: 56467
No need to extend Thread
class. The simpliest version is this:
import threading
def client_handler(connection):
#read request data
#process request
#reply response to **connection** object
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 10000)
sock.bind(server_address)
sock.listen(1)
while True:
connection, client_address = sock.accept()
threading.Thread(target=client_handler, args=(connection,)).start()
Now you may wrap your socket object into RequestHandler
class if you wish, that's fine. But you can't copy sockets. Just pass a reference instead: RequestHandler(connection)
. Why would you copy it anyway?
The reason it is not copyable is because it represents some system resource (i.e. the socket). If there were 2 objects pointing at the same resource then they would conflict with each other. And at C level it is extremely hard to synchronize pure file descriptors (sockets are simply numbers at C level) if there are multiple owners. So socket object is a sort of a unique "gateway" to the underlying file descriptor.
Upvotes: 1