Reputation: 1080
I am working on a server that continuously send data to a client. This client may also interact punctuality with the server sending a specific request. I wrote a daemon to do this. Note that this daemon works in a thread. For now, the script is structured as follows :
class MyDaemon(threading.Thread):
def __init__(self):
# Init Stream socket (output)
self.MainSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.MainSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.MainSock.bind(('', 15555))
self.MainSock.listen(5)
self.MainSock.setblocking(0)
# Init Request socket (input)
self.RequestSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.RequestSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.RequestSock.bind(('', 15556))
self.RequestSock.listen(5)
self.RequestSock.setblocking(0)
def run(self):
while True:
# Listen to connection on MainSock
try:
self.stream, address = self.MainSock.accept()
except:
pass
# Listen to connection on RequestSock
try:
self.request, address = self.RequestSock.accept()
except:
pass
if self.stream:
send_message_continuously() # it is a stream
if self.request:
recv_a_message_from_client()
do_whatever_action_the client_request()
The problem is that :
using only the steamer, all works fine.
using only the requester, all works fine.
using the two sockets at the same time blocks the streamer.
I read that a single thread cannot connect (or be connected) to two sockets at the same time. I also read that the use of the select
module may help to handle this kind of problem, but I never used it and I am a little bit lost about its use on my particular case.
What is the more efficient way to handle this problem ?
How to set up select
in my particular case ?
Wouldn't it be more efficent/simple to send stream to a sub-thread and request to another ?
EDIT : Finally, I used a sub-thread for the stream
Upvotes: 0
Views: 66
Reputation: 42748
When using select
you have to test, which of your two sockets is ready to accept:
def run(self):
while True:
ready, _, _ = select.select([self.MainSock, self.RequestSock],[],[])
for sock in ready:
if sock is self.MainSock:
send_message_continuously(sock.accept())
elif sock is self.RequestSock:
recv_a_message_from_client(sock.accept())
Upvotes: 2
Reputation: 4336
I suggest to you to try gevent, simple to understant the api, its good to go if you want to overcome the problem, there is a section about servers
to understand about tcp communication & rethink your current solution.
a code snap -
def handle(socket, address):
print('new connection!')
server = StreamServer(('127.0.0.1', 1234), handle) # creates a new server
server.start() # start accepting new connections
Hope you can spend more time on making the application without making skelts. :)
Upvotes: 1