现在,如果我的环境出现问题(某些读数显示默认情况下套接字默认是阻塞的), after creating each socket ,您可以添加(如一条注释中所指定的)以下行:
for s_global
s_global.setblocking(0)
for s_local
s_local.setblocking(0)
现在为了从两个套接字 receive incoming connections ,您应该使用 Python 的select module(用于异步IO) with no need for other threads ;您的服务器应用程序应该经常监听连接,例如:
TIMEOUT = 1 #seconds
terminate = False # variable to be modified externally to end the loop
listening_sockets = [s_global, s_local]
while (not terminate):
notified_socket_list = select.select(listening_sockets, [], [], TIMEOUT)[0]
for notified_socket in notified_socket_list:
incoming_socket, addr = notified_socket.accept()
handle(incoming_socket, addr)
2 回答
这可以在C中完成:Listen to multiple ports from one server
和C:Create multiple listening sockets
所以你应该能够用Python做到这一点 .
唯一能使这不安全的是你的服务器响应GUI执行危险的活动,但你可以添加代码来检查和防止黑客攻击 .
我正在使用
python2.7.3
,并且如我的评论中所述,我无法重现listen
阻止问题 . 笔记:为了简单起见我只使用
IPv4
套接字我包括
Python
's prompter in the code to show that it didn' t块关于最终的安全问题:监听9091的套接字(
s_local
),只接受来自localhost的连接(来自其他主机的连接将失败)这是CentOS5机器的一个片段:
这是同一台机器上的一些输出:
如图所示,两个服务器套接字都在监听连接 .
现在,如果我的环境出现问题(某些读数显示默认情况下套接字默认是阻塞的), after creating each socket ,您可以添加(如一条注释中所指定的)以下行:
现在为了从两个套接字 receive incoming connections ,您应该使用
Python
的select module(用于异步IO) with no need for other threads ;您的服务器应用程序应该经常监听连接,例如:注意:值得一提:epoll(
select.epoll
)是性能优先选择(select.select
),但我还没有尝试过 .现在,关于连接处理功能( handle ):如果您的服务器仅用于教育目的,您可以保持原样,但如果您的服务器设计为接受大量的同时连接和大量数据交换客户端,你应该在一个单独的 thread 中处理每个连接(这是一个不适用于
Python
的一般建议,因为它的GIL,有时线程只会减慢速度)/ process 在SocketServer.py - part of Python's standard library中完成 .@ Edit1 - 回复第1条评论:
这很简单,你所要做的就是修改内部的
for
循环:或者您可以使用我的原始解决方案并在 handle 中区分连接:
addr
参数包含套接字连接到的(本地)端口;您可以对其进行测试,并根据其值(9090或9091)以不同方式处理连接 .