【发布时间】:2016-04-27 11:13:42
【问题描述】:
python3socket programming howto 呈现这段代码 sn-p
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,则发送循环被中断。
这个sn-p背后的逻辑是当send方法返回'0 bytes sent'时,socket连接的发送端应该放弃发送数据的努力。这对于recv 方法肯定是正确的,在阻塞模式下为套接字读取的零字节应该被解释为EOF,因此读取端应该放弃。
但是我无法理解send 方法在哪些情况下会返回零。我对 python 套接字的理解是 send 由于在操作系统级别进行缓冲而立即返回。如果缓冲区已满send 将阻塞,或者如果连接在远程端关闭,则会引发异常。
最后假设send 返回零而不引发异常:这真的表明所有未来的send 调用都将返回零吗?
我已经进行了一些测试(尽管在 OS X 上仅使用连接到 ::1 的套接字)并且无法找到 send 返回 0 的情况。
编辑
HOWTO 规定:
但是,如果您打算重复使用您的套接字进行进一步的传输,您需要 意识到套接字上没有EOT。我再说一遍:如果一个套接字 send 或 recv 处理完 0 个字节后返回,连接已 破碎的。如果连接没有断开,您可以等待接收 永远,因为套接字不会告诉你什么都没有 更多内容(目前)。
很容易找到recv返回0的情况:当远程(发送)端调用socket.shutdown(SHUT_WR)时,接收端的进一步recv将返回0并且不会引发任何异常。
我正在寻找一个具体的例子,你可以证明从 send 接收到 0 零表示 连接断开(发送时将继续返回 0。)
【问题讨论】:
-
HOWTO 还解释说,“但是如果你打算重用你的套接字进行进一步的传输,你需要意识到套接字上没有 EOT。我重复一遍:如果套接字发送或接收之后返回处理 0 个字节,连接已断开。”
-
@J.J.Hakala 我尽力创造了一个
send在处理完 0 个字节后返回但找不到的情况。我在接收端尝试了几乎所有方法(关闭、关闭的各种组合等),但send方法从未返回 0。所以我的问题是send返回 0 的特殊情况是什么?
标签: python sockets python-3.x