成功发送send()"原子"吗?

lxg*_*xgr 4 sockets tcp atomicity

成功调用send()并返回的数字等于size参数中指定的数量,是否保证不会发生"部分发送"?

或者有什么方法可以在服务系统调用时中断操作系统,发送部分数据,等待可能很长时间,然后发送其余的并返回而不通知我更小的返回值?

我不是在讨论内核缓冲区空间不足的情况; 我意识到我会得到一个较小的返回值,并且必须再试一次.

更新: 根据目前为止的答案,我的问题可以改写如下:

在调用send()之前,有没有办法通过线路发送数据包/数据?

nos*_*nos 5

成功调用send()并返回的数字等于> size参数中指定的数量,是否保证不会发生"部分发送"?

不,有可能部分数据通过线路传递,而另一部分只能复制到本地TCP堆栈的内部缓冲区.send()将返回no.传递给本地TCP堆栈的字节数,而不是no.传递到线路上的字节数(即使数据到达线路,它也可能无法到达对等端).

或者有什么方法可以在服务系统调用时中断操作系统,发送部分数据,等待可能很长时间,然后发送其余的并返回而不通知我更小的返回值?

因为send()只返回no.传递到本地TCP堆栈的字节数,而不是send()实际上是否发送任何东西,你无论如何都无法区分这两种情况.但是,是的,可能只有一些数据可以通过网络实现.即使本地缓冲区中有足够的空间,对等体也可能没有足够的空间.如果发送2个字节,但是对等体只有1个字节的空间,则可能发送1个字节,另一个将驻留在本地tcp堆栈中,直到对等体再次有足够的空间.

(这是一个极端的例子,大多数TCP堆栈可以防止一次发送这么小的数据段,但是如果你尝试发送4k数据但同行只有3k的空间,则同样适用).

我不是在讨论内核缓冲区空间不足的情况; 我意识到我会得到一个较小的返回值,并且必须再试一次

只有在套接字无阻塞时才会发生这种情况.如果阻塞并且本地缓冲区已满,send()将等待,直到再次在本地缓冲区中存在空间(或者,如果部分数据已传送,则可能返回短计数,但同时发生错误.)

编辑回答:

在调用send()之前,有没有办法通过线路发送数据包/数据?

是.这可能由于许多原因而发生.例如

  • 最近的send()调用填充了本地缓冲区,并使用阻塞I/O.
  • TCP堆栈通过网络发送数据,但决定在发送过程从send()返回之前安排其他进程运行.