如何让服务器监听多个端口

6 投票
3 回答
23354 浏览
提问于 2025-04-18 16:03

我想让同一个服务器监听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()

3 个回答

0

关于第二个问题 - 使用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))
1

你可以在这里找到一个很好的解释:从一个服务器监听多个端口。虽然这个内容是关于C语言的,但在Python中遇到的问题是一样的。

所以答案也是一样的:

  • 每个端口需要一个套接字
  • 每个套接字需要一个监听
  • 只需要一个选择

顺便提一下,在Unix(以及类似Unix的)系统中,1024以下的端口是被保留的:你需要管理员权限才能使用它们。而在Windows系统中,没有这样的限制。

6

这里有两个问题。

  1. 1024以下的端口是被保留的。也就是说,你需要特别的权限,比如说管理员权限,才能使用这些端口。

  2. 一个套接字(socket)只能在一个端口上监听。所以如果你想同时监听多个端口,就需要为每个端口创建一个套接字。

撰写回答