在我的代码中我写了这样的东西:
try:
s.sendall(data)
except Exception as e:
print e
现在,我可以假设如果sendall没有抛出任何异常,那么套接字的另一端(它的内核)确实收到了'数据'吗?如果不是那么这意味着我需要发送一个对我来说似乎不合理的应用程序确认。
如果我可以假设对方的内核确实接收到'数据'那么这意味着'sendall'只有在看到tcp ack时才会返回我放入'data'的所有字节,但我看不到任何文档为此,相反,通过搜索网络,我感觉我不能认为收到了确认。
答案 0 :(得分:3)
我可以假设,如果sendall抛出任何异常,那么套接字的另一端(其内核)确实收到了数据'?
不,你不能。它告诉您系统已成功发送数据。它不会等待对等方确认数据(即在OS内核接收的数据),或者甚至等待对等应用程序处理数据。此行为不是特定于python。
通常,如果对等系统内核接收到数据并将其放入应用程序套接字缓冲区,则无关紧要。所有真正重要的是它是否接收并处理了应用程序内部的数据,这可能涉及复杂的事情,例如将数据插入数据库并等待成功提交甚至将数据转发到另一个系统。并且由于应用程序决定何时真正处理数据,因此您必须使用特定于应用程序的ACK来表示成功处理。
答案 1 :(得分:1)
是你可以:)
根据socket.sendall文档:
socket.sendall(string [,flags])将数据发送到套接字。插座 必须连接到远程套接字。可选的flags参数有 与上面的recv()的含义相同。与send()不同,这种方法 继续从字符串发送数据,直到所有数据都已发送 或者发生错误。成功后不返回任何内容。出错了,一个 引发异常,并且无法确定多少数据, 如果有的话,已成功发送。
具体做法是:
socket.sendall()
将继续发送所有数据,直至完成或发生错误。
更新:要回答您对下隐藏的内容的评论:
查看socketmodule.c源代码,看起来它反复尝试“发送所有数据”,直到没有剩余数据要发送。你可以在L3611 } while (len > 0);
上看到这个。希望这能回答你的问题。