Python:监听两个端口

5
import socket
backlog = 1 #Number of queues

sk_1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk_2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

local = {"port":1433}
internet = {"port":9999}

sk_1.bind (('', internet["port"]))
sk_1.listen(backlog)

sk_2.bind (('', local["port"]))
sk_2.listen(backlog)

基本上,我有这段代码。我正在尝试监听两个端口:1433和9999。但是,它似乎不起作用。

如何在同一个Python脚本中监听两个端口?

2个回答

11

如果你想使用 Python 标准库,最高端的方法是使用 ThreadingMixin 的 SocketServer。尽管 "select" 建议可能更有效。

即使我们只定义了一个 ThreadedTCPRequestHandler,你也可以轻松地将其重新用于每个监听器具有其自己独特的处理程序,并且将服务器/线程创建包装到单个方法中应该相当简单,如果那是你喜欢的类型的东西。

#!/usr/bin/python

import threading
import time
import SocketServer

class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        self.data = self.request.recv(1024).strip()
        print "%s wrote: " % self.client_address[0]
        print self.data
        self.request.send(self.data.upper())

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

if __name__ == "__main__":

    HOST = ''
    PORT_A = 9999
    PORT_B = 9876

    server_A = ThreadedTCPServer((HOST, PORT_A), ThreadedTCPRequestHandler)
    server_B = ThreadedTCPServer((HOST, PORT_B), ThreadedTCPRequestHandler)

    server_A_thread = threading.Thread(target=server_A.serve_forever)
    server_B_thread = threading.Thread(target=server_B.serve_forever)

    server_A_thread.setDaemon(True)
    server_B_thread.setDaemon(True)

    server_A_thread.start()
    server_B_thread.start()

    while 1:
        time.sleep(1)

4

目前为止的代码还可以,只要不超过一定范围(除了1个积压似乎太严格了),当然问题在于当您尝试在任何一个监听套接字上进行accept时,因为accept通常是阻塞调用(通过轮流尝试使用短超时时间在两个套接字上进行accept来“轮询”将浪费机器周期而无益)。

select 来拯救!-) select.select(或者更好的操作系统上的 select.poll 或者甚至 select.epollselect.kqueue...但是,老实的 select.select 在所有地方都能工作!-) 将让您知道哪个套接字已准备好以及何时准备好,因此您可以适当地进行accept。沿着这些线路,asyncoreasynchat 提供了更多组织(当然,第三方框架twisted添加了大量这样的“异步”功能)。

或者,您可以为两个侦听套接字分别分配线程,但在这种情况下,如果不同的套接字功能需要影响相同的共享数据结构,则协调(锁定等)可能变得棘手。我肯定会建议首先尝试异步方法-它实际上更简单,并且具有潜力实现更好的性能!-)


@mRt,你观察到bind调用有什么症状?它们似乎正确地绑定了所有可用接口上的两个端口(当然,这就是空字符串“host”的意思)。 - Alex Martelli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接