Ste*_*o M 13 python sockets python-3.x
python3 套接字编程如何呈现此代码片段
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)
Run Code Online (Sandbox Code Playgroud)
如果套接字send方法返回0 ,则发送循环中断.
这个片段背后的逻辑是,当send方法返回'0 bytes sent'时,套接字连接的发送方应该放弃发送数据的努力.这对于该recv方法肯定是正确的,其中在阻塞模式下为套接字读取的零字节应该被解释为EOF,因此读取方应该放弃.
但是我无法理解在哪种情况下该send方法可以返回零.我对python套接字的理解是send由于OS级别的缓冲而立即返回.如果缓冲区已满send将阻塞,或者如果远程端连接已关闭,则会引发异常.
最后假设send返回零而不引发异常:这是否真的表明所有未来的send调用都将返回零?
我做了一些测试(尽管::1在OS X上只连接了套接字)并且无法找到send返回0的情况.
编辑
HOWTO指出:
但是,如果您计划重新使用套接字进行进一步传输,则需要意识到套接字上没有EOT.我再说一遍:如果在处理0字节后套接字send或recv返回,则连接已断开.如果连接没有被破坏,你可以永远等待一个recv,因为套接字不会告诉你没有什么可读的(现在).
很容易找到recv返回0 的情况:当远程(发送)端调用时socket.shutdown(SHUT_WR),recv接收端的进一步返回0并且不会引发任何异常.
我正在寻找一个具体的例子,你可以证明接收0零send表示连接断开(在发送时将继续返回0).
看到问题后,我被震惊了,因为sendC调用可以返回0个字节并且连接当然仍然存在(套接字不能简单地在给定时刻发送更多字节)
我决定"使用源代码",除非我非常错(这可能一直是经常发生),这是HOWTO中的一个错误.
链:
send 是别名 sock_sendsock_send 轮流打电话 sock_callsock_call 轮流打电话 sock_call_exsock_call轮流调用sock_send_impl(从传递链接开始sock_send)平仓:
sock_send_impl返回true或false(1或0)return (ctx->result >= 0)
sock_call_ex 回报
-1如果sock_send_impl回来false0如果sock_send_impl回来truesock_call 透明地返回此值.
sock_send
返回NULLa -1(因为已经设置了错误并且将引发异常)
回报ctx->result为0从sock_call
而且ctx->result是由C调用写入的字节数send在sock_send_impl.
该链显示如果0已发送字节,则没有错误,这实际上是潜在的真实插座情况.
如果我的逻辑错了,请有人告诉我.
| 归档时间: |
|
| 查看次数: |
3083 次 |
| 最近记录: |