Python:收听两个端口

时间:2010-09-07 00:36:15

标签: python sockets listen

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 个答案:

答案 0 :(得分:11)

如果你想使用Python std-lib,那么花哨的方法就是将SocketServer与ThreadingMixin一起使用 - 尽管'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)

答案 1 :(得分:4)

到目前为止,代码很好,只要它的顺序是1(似乎过于严格),当你在任一侦听套接字上尝试accept连接时,问题就出现了,因为{ {1}}通常是一个阻塞调用(并且通过尝试接受任何套接字上的短暂超时来“轮询”会使机器周期燃烧到没有好处的目的。)

select救援! - )accept(或更好的操作系统select.select甚至select.pollselect.epoll ...但是,老了select.kqueue无处不在! - )会告诉您哪个套接字已准备就绪以及何时可以,因此您可以select.select进行适当的操作。在这些方面,acceptasyncore提供了更多的组织(和第三方框架asynchat,当然,添加了 lot 这样的“异步”功能)。

或者,您可以将单独的线程用于服务两个侦听套接字,但在这种情况下,如果不同套接字的功能需要影响相同的共享数据结构,则协调(锁定& c)可能变得棘手。我当然会建议首先尝试异步方法 - 它实际上更简单,并提供更好性能的潜力! - )