SocketServer 绑定多个服务器

3 投票
2 回答
1899 浏览
提问于 2025-04-18 07:37

我正在尝试用Python的SocketServer模块绑定多个服务器:

import SocketServer
from SocketServer import BaseRequestHandler

class HTTPSERVER(BaseRequestHandler):

    def handle(self):
        rec = self.request.recv(1024)
        if rec:
           self.request.send('Got something!')

launchme = SocketServer.TCPServer(('', 82),HTTPSERVER)
launchme2 = SocketServer.TCPServer(('', 81),HTTPSERVER)
launchme3 = SocketServer.TCPServer(('', 80),HTTPSERVER)
launchme.serve_forever()
print 'reached first server'
launchme2.serve_forever()
print 'reached second server'
launchme3.serve_forever()
print 'reached third server'

当这个脚本启动时,什么都没有打印出来,但实际上所有三个端口都是开放的:

root@user:/# netstat -pna|more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2751/python     
tcp        0      0 0.0.0.0:81              0.0.0.0:*               LISTEN      2751/python     
tcp        0      0 0.0.0.0:82              0.0.0.0:*               LISTEN      2751/python    

不过这个脚本只有在端口82(第一个绑定)上收到请求时才会返回“Got something!”。请问用SocketServer模块,怎样才能让所有端口都能正常工作呢?

2 个回答

0

我也在尝试做同样的事情,socketserver 的文档提到可以用 selectors 这个包来实现这个目标(如果我理解得没错的话),在描述 fileno() 方法时,提到:

这个方法会返回一个整数类型的文件描述符,它代表了服务器正在监听的那个 socket。这个函数通常会被传递给 selectors,这样就可以在同一个进程中监控多个服务器。

不过,我尝试了几个小时,还是没能写出能正常工作的代码。

5

server_forever 这个方法会一直处理请求,直到你明确地发出关闭的指令。

一旦你调用了 launchme.serve_forever(),后面的请求就不会再被处理了。你需要在不同的线程或者独立的进程中去调用它们。

import SocketServer
from SocketServer import BaseRequestHandler
import threading

class HTTPSERVER(BaseRequestHandler):

    def handle(self):
        rec = self.request.recv(1024)
        if rec:
           self.request.send('Got something!')

launchme = SocketServer.TCPServer(('', 82),HTTPSERVER)
launchme2 = SocketServer.TCPServer(('', 81),HTTPSERVER)
launchme3 = SocketServer.TCPServer(('', 80),HTTPSERVER)
t1 = threading.Thread(target=launchme.serve_forever)
t2 = threading.Thread(target=launchme2.serve_forever)
t3 = threading.Thread(target=launchme3.serve_forever)
for t in t1, t2, t3: t.start()
for t in t1, t2, t3: t.join()

撰写回答