我使用“select”编写了一个基本套接字系统。我希望立即获得连接客户的列表。
当“选择”的超时已经过去并且有几个客户来之后,这就是戏剧......
示例 - 关注: 我有3个客户端,其中一个在超时之前连接,另外两个在超时后连接,所以如果在超时后考虑其他两个客户端,我将刷新我的列表。
第一个结果:我显示我的变量“list”,我看到超时之前连接的第一个套接字+超时后连接的另一个套接字之一。总计:3个客户中的2个
第二个结果:我仍然重新显示我的变量“list”,三个客户端就在那里......
但是我想要列表而不必每次为每个客户重新显示列表我可以想象我有10个客户并且我必须显示我的上述次数
所以我想使用更流畅的asyncore模块,你怎么看?你有解决方案(更容易)吗?我应该使用多线程还是留在asyncore或选择模块?
编辑代码来源:
import socket, select
hote = ''
port = 81
mainConnection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mainConnection.bind((hote, port))
mainConnection.listen(5)
print("Listen to {}".format(port))
client_online = []
while True:
connection_access, wlist, xlist = select.select([mainConnection], [], [], 10)
for connexion in connection_access:
connection_client, infos_connexion = connexion.accept()
client_online.append(connection_client)
refresh = input(">>> ")
while True:
try:
refresh = int(refresh)
except ValueError:
print("Not allowed")
refresh = int(refresh)
else:
break
if refresh == 1:
print("List client : {}".format(client_online))
答案 0 :(得分:1)
您的代码存在三个主要问题:
您在循环中调用input
。此功能将阻止,直到按下 ENTER 。
如果从控制台输入非整数,您将收到异常。您处理该异常,但是您处理错误。相反或者再次请求输入,您只需尝试执行导致异常的相同操作。
您只需检查select
来电中的来电连接。您永远不会检查是否有任何已连接的套接字已发送任何内容。
这里的主要问题是对input
的调用,因为它会完全停止你的程序,直到输入来自控制台的输入。
答案 1 :(得分:0)
你的帖子很不清楚,但我可以告诉你问题是你不了解如何使用select
。
您发布的代码只会选择一次。程序进入select()
调用并等待mainConnection
可读(或超时)。如果mainConnection
在超时之前变为可读,select()
将返回一个可读文件描述符,然后您可以在for
循环中处理该文件描述符。但那就是它。永远不会再调用select
,因此您的程序永远不会检查是否有更多的传入连接。
几乎每个应用程序select
都应该处于循环中。每次循环时,程序都会在select()
调用中等待,直到一个或多个套接字准备好进行读取或写入。当发生这种情况时,select
会为您提供准备好的文件描述符,并且让其他代码实际执行某些操作是您的工作。例如,如果select
将套接字的文件描述符返回为可读,那么您的工作就是在该套接字上调用.recv()
。
你当然可以使用asyncore。事实上,我认为您应该研究asyncore的源代码,以了解如何正确使用select
。