1

我用“select”编写了一个基本的套接字系统。我想立即获得连接的客户端列表。

当“选择”的超时时间过去了,几个客户来了,这就是戏剧。

示例 - 问题:我有 3 个客户端,其中一个在超时前连接,另外 2 个在超时后连接,所以如果在超时后考虑到另外两个客户端,我将刷新我的列表。

第一个结果:我显示我的变量“列表”,我看到在超时前连接的第一个套接字 + 在超时后连接的另一个套接字。总计:3 个客户中的 2 个

第二个结果:我仍然重新显示我的变量“列表”,三个客户端都在那里....

但是我想要这个列表,而不必每次都为每个客户重新显示列表,你可以想象我有 10 个客户,我必须显示我的列表 10 次

所以我想用更流畅的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))
4

2 回答 2

1

您的代码存在三个主要问题:

  1. 你打电话给input你的循环。此功能将阻塞,直到ENTER被按下。

  2. 如果从控制台输入非整数,则会出现异常。你处理了那个异常,但是你错误地处理了它。相反,或者再次请求输入,您只需尝试再次执行导致异常的相同操作。

  3. 您只检查select通话中的传入连接。你永远不会检查任何连接的套接字是否发送了任何东西。

对您来说,这里的主要问题是调用,input因为它会完全停止您的程序,直到输入来自控制台的输入。

于 2013-06-24T03:29:41.387 回答
0

您的帖子非常不清楚,但我可以告诉您,问题在于您不了解如何使用select.

您发布的代码只调用一次选择。程序开始select()调用并等待mainConnection可读(或超时)。如果mainConnection在超时之前变得可读,则select()返回一个可读的文件描述符,然后您将在for循环中对其进行处理。但就是这样。select永远不会再次调用,因此您的程序永远不会检查任何更多的传入连接。

在几乎每个应用程序select中都应该循环。每次通过循环,程序都会在select()调用中等待,直到一个或多个套接字准备好进行读取或写入。发生这种情况时,会select为您提供准备好的文件描述符,让其他代码实际执行某些操作是您的工作。例如,如果select将套接字的文件描述符返回为可读的,则调用.recv()该套接字是您的工作。

你当然可以使用异步。其实我觉得你应该研究一下 asyncore 的源代码来学习如何正确使用select.

于 2013-06-24T01:13:16.343 回答