前段时间我有一个问题,为什么我的套接字有时只收到653个八位字节(例如),当我发送1024个八位字节时,感谢Rakis我理解:操作系统允许接收以任意大小的块发生。
这次我需要确认:)
在任何操作系统上(至少是GNU / Linux和Windows),在任何语言中(我在这里使用Python),如果我发送一个随机数字的数据包,可以是2个字节,可以是12000个字节,让我们说X,当我写socket.send(X)时,我绝对保证在另一个套接字之前,套接字另一端的X将被完全接收(无论接收操作系统将其分成什么块)。发送(任何字符串)?
或者换句话说,如果我有代码:
socket.send(X)
socket.send(Y)
即使X> MTU所以它必须发送多个数据包,是否等待每个数据包发送并在发送Y之前由套接字的端点确认?写得好,让我相信答案是肯定的,这是有保证的,这正是在阻塞模式下设置套接字的目的,但我想确定:D
提前致谢, Nolhian
答案 0 :(得分:2)
如果它是流套接字,那么可以保证在Y之前将收到(在应用程序级别)。如果它是数据报套接字,则无法保证。
根据网络实施,可能在较低级别,X将被发送,在传输中丢失,然后Y将被发送,然后X将被重新发送,因为没有收到确认。
即使在阻塞模式下,socket.send(Y)也可以在X甚至使其“连线”之前执行,因为操作系统将缓冲网络流量。
答案 1 :(得分:2)
不,你不能。
所有你知道的是,客户端将按顺序接收数据,假设它 接收所有数据。没有办法知道(在应用程序级别)客户端是否已收到所有数据而没有在应用程序级别协议中使用某种“ACK”。
答案 2 :(得分:0)
我绝对保证在另一个socket.send(任何字符串)之前,套接字另一端的X将被完全接收(无论接收操作系统划分的任何块)
没有。通常,在某些限制内,可以在不等待接收方的情况下发送更多数据:
在发送方,您将拥有最大数量的数据,您可以将其排入传输,直到客户端确认收到某些收据(但通常客户端的操作系统会在拒绝进一步数据之前确认并缓冲很多应用程序已经处理了一些),之后发送套接字可能会开始阻塞
因此,严格来说,对于大型传输,发送方应设计为处理被阻止进一步发送的套接字(要么知道可以阻止尝试(可能是由于专用的发送线程),要么等到可能通过非阻塞套接字或选择/轮询发送更多信息。
无论需要重传和缓冲,您可以确定的是接收方必须在开始给出随后发送的数据“Y”之前读取所有“X”(除非具体请求另外,例如带外数据。
答案 3 :(得分:-1)
根据您使用的type of Sockets,在某些情况下,您可以保证会收到数据,但实际上不会收到反馈或确认。
回到你的问题:
在发送Y之前,它是否等到套接字的端点发送和确认之后
所以,你可以说:
建议:
由于没有自动魔术/内置确认您的数据已收到,因此您可以非常轻松地实施自己的逻辑,以便ACK
现在使用收到了包,这基本上归结为自定义通信协议。