gpt4 book ai didi

python - Python 中的 recv()

转载 作者:太空狗 更新时间:2023-10-29 22:23:08 25 4
gpt4 key购买 nike

open_sockets = []

listening_socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )

listening_socket.bind( ("", 1234) )

listening_socket.listen(5)

while True:
rlist, wlist, xlist = select.select( [listening_socket] + open_sockets, [], [] )
for i in rlist:
if i is listening_socket:
new_socket, addr = listening_socket.accept()
open_sockets.append(new_socket)
else:
data = i.recv(1024)
if data == "":
i.close()
open_sockets.remove(i)
print "Connection closed"
else:
i.send(data)
print repr(data)

现在我知道这是可以处理几个客户端的简单服务器代码 - 我唯一不明白的是这两行:

        data = i.recv(1024)
if data == "":

我知道当客户端已经接受时,它会转到另一个选项,即检查缓冲区中是否有内容的选项。我不明白为什么,当缓冲区中没有任何内容时,它会继续并且不检查行:

if data == "":

但是当客户端只按下相当于""的回车键时,它会断开连接

为什么当什么都不按时它和""不一样?

最佳答案

它以 select 开头称呼。此函数监视套接字并等待值得注意的事情发生。对于第一个列表中的套接字,“值得注意”意味着该套接字有可供读取的数据。

rlist, wlist, xlist = select.select( [listening_socket] + open_sockets, [], [] )

代码现在遍历套接字列表并准备读取数据,并根据正在处理的套接字类型采取行动。

    for i in rlist:
if i is listening_socket:

面向连接(“监听”)的套接字用于接受新连接。因为它在 rlist 中,我们知道它有一些东西供我们“阅读”。在监听套接字的上下文中,这意味着已接收到新连接。所以我们接受连接,并将新套接字保存在 open_sockets 列表中。

            new_socket, addr = listening_socket.accept()
open_sockets.append(new_socket)

如果套接字不是listening_socket,那么它是一个连接到(或曾经)连接到远程客户端的套接字。而且由于它在 rlist 中,我们知道它有一些东西供我们“阅读”。在已连接套接字的上下文中,这意味着数据实际上可以读取,或者套接字已关闭。

所以我们调用recv 来获取任何可用数据,

        else:
data = i.recv(1024)

看看我们是否真正阅读了任何内容。如果没有可用数据,则连接一定已关闭,因此我们关闭套接字对象并将其从 open_sockets 中删除。

            if data == "":
i.close()
open_sockets.remove(i)
print "Connection closed"

如果我们确实收到了数据,我们只是将其写回客户端并打印在屏幕上。

            else:
i.send(data)
print repr(data)

select 的第一次调用将等待直到收到连接。您可以通过将代码更新为

print "About to call select"
rlist, wlist, xlist = select.select( [listening_socket] + open_sockets, [], [] )
print "Returned from select"

第一次调用后,rlist 将包含listening_socket。我们知道这一点是因为 open_sockets 是空的,而所谓​​的 select 将不会返回,直到某些内容被读取为“读取”。所以我们接受新连接并将其添加到 open_sockets

当再次调用select 时,可能会发生三种情况。首先,listening_socket 可能收到了另一个连接。在这种情况下,它的处理方式和以前一样:我们接受连接并将其添加到 open_sockets

其次,新连接可能已经接收到数据。由于 select 将其包含在 rlist 中,我们知道有数据准备好从套接字中“读取”(意味着数据已准备好读取,或者套接字已关闭). i.recv 将返回新数据。

第三,新连接可能已经关闭。由于select将其包含在rlist中,我们知道有数据准备从套接字中读取(含义同上)。但是 i.recv 将返回 ""因为套接字没有任何新数据。所以我们知道套接字已经关闭,并进行相应的清理。

如果客户端没有发送任何数据(并且连接仍然打开),则select 将不会将其包含在rlist 中。所以循环不会处理它,并且 i.recv 不会在那个特定的套接字上被调用。

关于python - Python 中的 recv(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13771937/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com