Python TCP同时监听多个端口的方法

3
我正在构建一个Python服务器,基本上有一堆端口监听连接。当建立连接时,端口会输出一条消息,关闭连接并重置(即等待下一个连接)。
期望的功能:
为端口列表中的每个端口创建TCP套接字(通过参数动态填充)。
监听连接。
当建立连接时,发送消息并断开连接。
继续监听。
我感觉我的答案可能涉及到多线程,但我不确定......目前我的代码如下:
  for port in portlist:
    ds = ("0.0.0.0", port)

    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind(ds)
    server.listen(1)
    while 1:
            connection, address = server.accept()
            message="message\n"
            connection.send(message)
            connection.close()

目前,您的代码在第一个套接字上侦听,然后循环以接受客户端。您应该将while循环移动到for循环之外。棘手的不是在许多端口上侦听,而是从许多端口接受和服务客户端连接:为此,您可以使用select模块的selectepoll函数来指定要监视的端口,并循环处理报告活动的端口,或者使用线程。 - Tony Delroy
相关问题在这里 - 回答提到SocketServer似乎是处理这个问题的一种非常简单的方法。 - Tony Delroy
1个回答

9

在监听端,有一种单线程的方法(实际处理连接可能仍然需要多个线程)。

您应该预先打开所有套接字,并将它们放入列表中。

然后,您应该在所有套接字上执行select操作,当任何一个准备好进行accept时,会返回结果。

类似于以下代码(未经测试):

servers = [] 

for port in portlist:
    ds = ("0.0.0.0", port)

    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind(ds)
    server.listen(1)

    servers.append(server)

while True:
    # Wait for any of the listening servers to get a client
    # connection attempt
    readable,_,_ = select.select(servers, [], [])
    ready_server = readable[0]

    connection, address = ready_server.accept()

    # Might want to spawn thread here to handle connection,
    # if it is long-lived

它似乎不喜欢select.select(servers, None,None)。TypeError: 参数1-3必须是序列。 - Lexicon
@Lexicon 将它们更改为空列表([])。 - Jonathon Reinhart
一旦连接建立,我该如何处理消息?(即我的代码中的消息部分) - Lexicon
@Lexicon 一旦建立连接,您将使用connection对象接收数据。对于给定的TCP套接字(SOCK_STREAM => TCP),您可以执行data = connection.recv(bufSize)。bufSize可以是任何字节数,比如1024。 - GiriB
以上代码将无法正常工作。select.select()返回三个准备好的对象列表,您需要的套接字对象包含在第一个列表中。要获取套接字对象,请执行ready_server = select.select(servers, [], [])[0][0] - GiriB
@GiriB 谢谢。正如我所说,我从未测试过它。我已经更新了代码。 - Jonathon Reinhart

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