Ipse Lium
Ipse Lium

Reputation: 1080

Python , communication through two sockets

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 :

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 selectin 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

Answers (2)

Daniel
Daniel

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

Renjith Thankachan
Renjith Thankachan

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

Related Questions