Python 如何使服务器侦听多个端口

Python 如何使服务器侦听多个端口,python,sockets,Python,Sockets,我想在同一台服务器上监听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,1

我想在同一台服务器上监听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()
它返回一个错误,说明
权限被拒绝
。是因为某些端口(1000-1100)被保留且未分配给它,还是因为其他原因

我尝试了(8000-8100),它显示
无效参数

已编辑

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()
有两个问题

  • 端口是保留的。(您需要特殊权限,例如绑定到此类端口的根权限)

  • 套接字只能在一个端口侦听。因此,要侦听多个端口,需要为每个端口创建一个套接字


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

    >>> 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))
    
    >s=socket.socket()
    >>>s.bind(('localhost',8001))
    >>>s.bind(('localhost',8001))
    回溯(最近一次呼叫最后一次):
    文件“”,第1行,在
    文件“/usr/lib64/python2.7/socket.py”,第224行,meth格式
    返回getattr(self.\u sock,name)(*args)
    socket.error:[Errno 22]参数无效
    >>>美国关闭
    >>>s.bind(('localhost',8001))
    回溯(最近一次呼叫最后一次):
    文件“”,第1行,在
    文件“/usr/lib64/python2.7/socket.py”,第224行,meth格式
    返回getattr(self.\u sock,name)(*args)
    文件“/usr/lib64/python2.7/socket.py”,第170行,在
    引发错误(EBADF,“错误的文件描述符”)
    socket.error:[Errno 9]错误的文件描述符
    >>>s=socket.socket()
    >>>s.bind(('localhost',8001))
    
    您可以在这里找到一个很好的解释:。这是针对C语言的,但python中的问题是相同的

    所以答案是一样的:

    • 每个端口一个插座
    • 每个插座听一次
    • 单选

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

    谢谢您的快速回复。正如我所想,1000-1100必须保留,因此被拒绝。谈论第二点!!!这意味着要监听100个不同的端口,我需要创建100个不同的套接字对象?这意味着我需要手动执行,一遍又一遍地写入相同的LOC,或者我也可以围绕它进行循环?当然,您可以使用一个循环来创建套接字并绑定它。将socket()调用的返回值保存在一个列表中,并将其传递给select(),它是这样的吗?我已经用我目前正在做的解决方案编辑了我的问题。对吗?请确认是的。如果s是服务器套接字,您还需要更改
    ,以检查它是否是您的服务器套接字之一-这意味着您可能需要两个列表,一个是服务器套接字,另一个是传递给select()的所有套接字,但是我将如何绑定多个端口/从多个端口接收数据?我会说:使用多个SocketServer(或SocketServer)实例,这些实例绑定到不同的端口,然后将它们绑定到同一个u handle_回调函数。我的C知识非常少。我搞不清楚到底发生了什么。你能用python提供类似的代码吗。这将大有帮助。谢谢