2015-04-22 109 views
2

在我的代码我写的是这样的:当python socket.sendall成功返回时,它意味着什么?

try: 
    s.sendall(data) 
except Exception as e: 
    print e 

现在,我可以假设,如果没有通过sendall在插槽(其内核)的另一端确实收到“数据”抛出的任何异常?如果不是这样,那意味着我需要发送一个应用程序,这对我来说似乎不合理。

如果我可以假设对方的内核确实收到'数据',那么这意味着'sendall'只有在它看到tcp ack时才会返回所有输入'data'的字节,但我看不到相反,通过搜索网络,我得到了一种感觉,我不能假设已经收到了答案。

回答

3

我可以假设,如果没有任何由sendall抛出的异常,套接字(它的内核)的另一端确实收到'数据'?

不,你不能。它会告诉你系统成功发送了数据。它不会等待对方确认数据(即在操作系统内核收到的数据),甚至不等待对等应用程序处理数据。这种行为并不特定于python。

通常,如果对等系统内核收到数据并将其放入应用程序套接字缓冲区中,则无关紧要。所有真正重要的是如果它接收和处理应用程序内的数据,这可能涉及复杂的事情,如将数据插入数据库并等待成功提交或甚至将数据转发到另一个系统。由于应用程序决定何时处理数据,因此必须使应用程序特定的ACK指示成功处理。

1

可以:)

按照socket.sendall文档:

socket.sendall(字符串[,标志])将数据发送到插座。插座 必须连接到远程插座。可选的flags参数具有 与上述recv()的含义相同。与send()不同,此方法 继续从字符串发送数据,直到发送所有数据为 或发生错误。没有成功返回。如果发生错误,将引发一个异常,并且无法确定成功发送了多少数据(如果有的话)。

具体做法是:

socket.sendall()将继续发送的所有数据,直到它已经完成或错误发生。

更新:要获得关于正在发生的事情下评论:

望着socketmodule.c源代码,它看起来像它反复尝试“发送的所有数据”,直到没有更多的数据留下发送。你可以在L3611 } while (len > 0);上看到。希望这可以回答你的问题。

+0

谢谢。我读到了这一点,但我不明白完成发送数据的意义。这是否意味着内核完成了发送或者是否意味着它从服务器获得了一个确认。从查看错误代码,我没有看到任何错误,说我没有得到一个答案。 – Ezra

+0

再次感谢。我解释这一点的方式是循环继续,直到缓冲区为空,直到它收到确认。我也在SO上找到了这个答案,它表示发送并不等待一个确认。 http://stackoverflow.com/questions/8218785/how-can-i-explicitly-wait-for-a-tcp-ack-before-proceeding – Ezra

+0

正确:)相信(*可能是错误的* *)''ACK ''/''NAK''在TCP堆栈中较低。这里我们正在处理TCP AFAIK之上的一个Socket。尝试wiresharking你的数据包流:) –

相关问题