Python,通过两个套接字进行通信

2024-10-04 01:30:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个服务器上工作,它不断地向客户机发送数据。该客户机还可以与发送特定请求的服务器进行准时交互。我写了一个守护进程来做这个。注意,这个守护进程在线程中工作。目前,脚本的结构如下:

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()

问题是:

  • 只用蒸笼,一切正常。

  • 只使用请求者,一切正常。

  • 同时使用两个插座会阻塞拖缆。

我读到一个线程不能同时连接到两个套接字。我还了解到使用select模块可能有助于处理这类问题,但我从未使用过它,我对它在我的特定案例中的使用感到有点迷茫。你知道吗

处理这个问题最有效的方法是什么? 如何在我的特殊情况下设置select? 将发送到子线程并将请求发送到另一个子线程不是更有效/更简单吗?你知道吗

编辑:最后,我为流使用了一个子线程


Tags: selfstream客户机进程initrequestdefsocket
2条回答

我建议您尝试gevent,简单易懂的api,如果您想克服这个问题,可以使用它,这里有一节关于servers 了解tcp通信并重新考虑您当前的解决方案。
代码快照-

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

希望你能花更多的时间来制作这个应用程序,而不必费劲。:)

使用select时,必须测试两个套接字中的哪一个可以接受:

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())

相关问题 更多 >