【问题标题】:How do I make a server listen on multiple ports如何让服务器监听多个端口
【发布时间】:2014-08-05 18:08:53
【问题描述】:

我想在同一台服务器上监听 100 个不同的 TCP 端口。这是我目前正在做的事情:-

import socket
import select

def main():

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    for i in range(1000,1100):
        server_socket.bind(('127.0.0.1', i))
    server_socket.listen(1)

    read_list = [server_socket]
    while True:
        readable, writable, exceptional = select.select(read_list, [], read_list)
        for s in readable:
            if s is server_socket:
                #print "client connected"
                client_socket, address = server_socket.accept()
                read_list.append(client_socket)
            else:
                # One of the tcp clients
                data = s.recv(1024)
                if not result:
                    s.close()
                    read_list.remove(s)
                    #print "client disconnected"

if __name__ == "__main__":
    main()

它返回一个错误说Permission Denied。是因为某些端口(1000-1100)被保留而没有分配给它还是因为其他一些原因?

我尝试使用 (8000-8100) 并显示 Invalid Arguments

已编辑

import socket
import select

def create_socket(TCP_PORT):
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(('127.0.0.1', TCP_PORT))
    server_socket.listen(1)

    return server_socket


def main():

    read_list = []

    for TCP_PORT in range(8000,8100):
        read_list.append(create_socket(TCP_PORT))

    while True:
        readable, writable, exceptional = select.select(read_list, [], read_list)
        for s in readable:
            if s is server_socket:
                #print "client connected"
                client_socket, address = server_socket.accept()
                read_list.append(client_socket)
            else:
                # One of the tcp clients
                data = s.recv(1024)
                if not result:
                    s.close()
                    read_list.remove(s)
                    #print "client disconnected"

if __name__ == "__main__":
    main()

【问题讨论】:

    标签: python sockets


    【解决方案1】:

    有两个问题。

    1. 端口below 1024 被保留。 (您需要特殊权限,例如绑定到此类端口的 root 权限)。

    2. 一个套接字只能监听一个端口。所以要监听多个端口,你需要为每个端口创建一个套接字。

    【讨论】:

    • 感谢您的快速回复。正如我所想,必须保留 1000-1100,因此权限被拒绝。谈第二点!!!意思是要监听100个不同的端口,我需要制作100个不同的socket对象?
    • 这意味着我需要手动执行,一遍又一遍地编写相同的 LOC,还是我也可以循环它?
    • 当然,您可以使用循环来创建套接字并绑定它。将 socket() 调用的返回值保存在一个列表中,然后传递给 select()
    • 会是这样吗?我已经用我目前正在做的解决方案编辑了我的问题。这是对的吗?请确认
    • 是的。您还需要更改 if s is server_socket,以检查它是否是您的服务器套接字之一 - 这意味着您可能需要 2 个列表,一个包含您的服务器套接字,一个包含您传递给 select 的所有套接字()
    【解决方案2】:

    你会在这里找到一个很好的解释:Listen to multiple ports from one server。它适用于C,但python中的问题是一样的。

    所以答案是一样的:

    • 每个端口一个套接字
    • 每个套接字监听一次
    • 单选

    顺便说一下,在 Unix(和类 Unix)系统上保留了 1024 以下的端口:您需要 root 权限才能使用它们。在 Windows 上,没有这样的限制。

    【讨论】:

    • 我的C知识很少。我无法弄清楚到底发生了什么。你能在python中提供类似的代码吗?这将有很大的帮助。谢谢
    【解决方案3】:

    关于第二个问题 - 使用端口 8000-8100 会导致Invalid argument,如果您尝试重新绑定已绑定的套接字而不首先重新创建套接字,则会发生这种情况。但是,该端口范围没有问题。

    >>> s=socket.socket()
    >>> s.bind(('localhost', 8001))
    >>> s.bind(('localhost', 8001))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib64/python2.7/socket.py", line 224, in meth
        return getattr(self._sock,name)(*args)
    socket.error: [Errno 22] Invalid argument
    >>> s.close()
    >>> s.bind(('localhost', 8001))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib64/python2.7/socket.py", line 224, in meth
        return getattr(self._sock,name)(*args)
      File "/usr/lib64/python2.7/socket.py", line 170, in _dummy
        raise error(EBADF, 'Bad file descriptor')
    socket.error: [Errno 9] Bad file descriptor
    >>> s=socket.socket()
    >>> s.bind(('localhost', 8001))
    

    【讨论】:

    • 我明白了,但是我将如何绑定multiple 端口/从多个端口接收数据。?
    • 我想说:使用绑定到不同端口的多个SocketServer(或socketserver)实例,然后将它们全部绑定到同一个__handle_callback函数。
    猜你喜欢
    • 2021-07-10
    • 2011-05-20
    • 1970-01-01
    • 2016-02-08
    • 2021-10-07
    • 2013-03-11
    • 2012-12-29
    • 2017-03-30
    • 1970-01-01
    相关资源
    最近更新 更多