gpt4 book ai didi

python - 何时以及为何 socket.send() 在 python 中返回 0?

转载 作者:太空狗 更新时间:2023-10-29 17:33:24 24 4
gpt4 key购买 nike

python3 socket programming howto呈现此代码片段

class MySocket:
"""demonstration class only
- coded for clarity, not efficiency
"""

def __init__(self, sock=None):
if sock is None:
self.sock = socket.socket(
socket.AF_INET, socket.SOCK_STREAM)
else:
self.sock = sock

def connect(self, host, port):
self.sock.connect((host, port))

def mysend(self, msg):
totalsent = 0
while totalsent < MSGLEN:
sent = self.sock.send(msg[totalsent:])
if sent == 0:
raise RuntimeError("socket connection broken")
totalsent = totalsent + sent

def myreceive(self):
chunks = []
bytes_recd = 0
while bytes_recd < MSGLEN:
chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048))
if chunk == b'':
raise RuntimeError("socket connection broken")
chunks.append(chunk)
bytes_recd = bytes_recd + len(chunk)
return b''.join(chunks)

如果套接字 send 发送循环被中断方法返回 0。

此代码段背后的逻辑是,当send 方法返回“0 bytes sent”时,套接字连接的发送方应放弃发送数据的努力。这对于 recv 肯定是正确的方法,其中在阻塞模式下为套接字读取的零字节应解释为 EOF,因此读取方应放弃。

但是我不明白在什么情况下 send 方法会返回零。我对 python 套接字的理解是 send 由于操作系统级别的缓冲而立即返回。如果缓冲区已满,send 将阻塞,或者如果连接在远程端关闭,则会引发异常。

最后假设 send 返回零而不引发异常:这是否真的表明所有 future 的 send 调用都将返回零?

我已经做了一些测试(尽管在 OS X 上只使用连接到 ::1 的套接字)并且无法找到 send 返回 0 的情况.

编辑

HOWTO 声明:

But if you plan to reuse your socket for further transfers, you need to realize that there is no EOT on a socket. I repeat: if a socket send or recv returns after handling 0 bytes, the connection has been broken. If the connection has not been broken, you may wait on a recv forever, because the socket will not tell you that there’s nothing more to read (for now).

很容易找到recv 返回0 的情况:当远程(发送)端调用socket.shutdown(SHUT_WR) 时。 ,接收端的进一步 recv 将返回 0 并且不会引发任何异常。

我正在寻找一个具体的示例,您可以在其中显示从 send 接收到 0 表示 断开的连接(它将继续在发送时返回 0。)

最佳答案

看到这个问题后我不知何故感到震惊,因为 send C 调用可以返回 0 字节并且连接当然仍然存在(套接字不能简单地在给定时刻发送更多字节)

我决定“使用源代码”,除非我大错特错(这可能总是而且经常是),否则这是 HOWTO 中的错误。

链:

  • sendsock_send
  • 的别名
  • sock_send依次调用sock_call
  • sock_call 依次调用sock_call_ex
  • sock_call 依次调用 sock_send_impl(已沿以 sock_send 开始的链向下传递)

展开:

  • sock_send_impl 返回 truefalse(1 或 0),return (ctx->result >= 0 )

  • sock_call_ex 返回

    • -1 如果 sock_send_impl 返回 false
    • 0 如果 sock_send_impl 返回 true
  • sock_call 透明地返回这个值。

  • sock_send

    • -1 返回 NULL(因为已设置错误并将引发异常)

    • sock_call

      0 返回 ctx->result

      ctx->resultsock_send_impl中C调用send写入的字节数。

链显示如果 0 字节已发送,则没有错误,这实际上是一个潜在的真实套接字情况。

如果我的逻辑有误,请告诉我。

关于python - 何时以及为何 socket.send() 在 python 中返回 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34919846/

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