使用返回的数字成功调用send()是否等于size参数中指定的数量,是否保证不会发生“部分发送”?
或者是否有某种方式可以在服务系统调用时中断操作系统,发送部分数据,等待可能很长时间,然后发送其余的并返回而不通知我更小的返回值?
我不是在讨论内核缓冲区空间不足的情况;我意识到我会得到一个较小的返回值,并且必须再试一次。
更新 根据目前为止的答案,我的问题可以改写如下:
在调用send()之前,有没有办法通过电线发送数据包/数据?
答案 0 :(得分:5)
使用返回的数字成功调用send()是否等于> size参数中指定的数量,以确保不会发生“部分发送”?
不,有可能部分数据通过线路传递,而另一部分只能被复制到本地TCP堆栈的内部缓冲区中。 send()将返回no。传递给本地TCP堆栈的字节数,而不是no。传递到线路上的字节数(即使数据到达线路,它也可能无法到达对等线。)
或者是否有某种方式可以在服务系统调用时中断操作系统,发送部分数据,等待可能很长时间,然后发送其余的并返回而不通知我更小的返回值?
as send()只返回no。传递到本地TCP堆栈的字节数,而不是send()实际上是否发送任何东西,你无论如何都无法区分这两种情况。但是,是的,可能只有一些数据可以通过网络实现。即使本地缓冲区中有足够的空间,对等体也可能没有足够的空间。如果你发送2个字节,但是对等体只有1个字节的空间,可能会发送1个字节,另一个将驻留在本地tcp堆栈中,直到对等体有足够的空间。
(这是一个极端的例子,大多数TCP堆栈可以防止一次发送这么小的数据段,但是如果你尝试发送4k数据但同行只有3k的空间,则同样适用。)
我不是在讨论内核缓冲区空间不足的情况;我意识到我会得到一个较小的返回值,并且必须再试一次
只有在套接字无阻塞时才会发生这种情况。如果它被阻塞并且本地缓冲区已满,send()将等待,直到再次在本地缓冲区中有空间(或者,它可能会返回 如果部分数据已交付,则为短计数,但同时发生错误。)
编辑回答:
在send()调用返回之前,有没有办法通过线路发送数据包/数据?
是。这可能由于许多原因而发生。 e.g。
答案 1 :(得分:3)
虽然这取决于您使用的协议,但一般问题是否。
对于TCP,数据在内核中缓冲,然后由TCP分组化算法自行决定发送,这非常多毛 - 它保留了多个定时器,介意路径MTU试图避免IP分段。
对于UDP,如果您的数据报不超过链接帧大小(通常值为1472 = 1500以太网帧--20个字节的IP报头 - 8个字节的UDP报头),您只能假设这种“原子性”。否则,您的发送主机必须对数据报进行IP分段。
如果中间路由器的出站链路MTU小于数据包大小,则它仍然可以对传递的数据包进行IP分片。