问题描述
成功调用 send() 并且返回的数量等于 size 参数中指定的数量是否保证不会发生部分发送"?
Does a successful call to send() with the number returned equal to the amount specified in the size parameter guarantee that no "partial sends" will occur?
或者有什么方法可以让操作系统在为系统调用提供服务时被中断,发送部分数据,等待可能很长时间,然后发送其余部分并返回而不用较小的返回值通知我?
Or is there some way that the OS might be interrupted while servicing the system call, send part of the data, wait for a possibly long time, then send the rest and return without notifying me with a smaller return value?
我不是在谈论内核缓冲区空间不足的情况;我意识到我会得到一个较小的返回值并且必须再试一次.
I'm not talking about a case where there is not enough room in the kernel buffer; I realize that I would then get a smaller return value and have to try again.
更新:根据目前的答案,我的问题可以改写如下:
Update:Based on the answers so far, my question could be rephrased as follows:
在调用 send() 返回之前有没有办法通过线路发送数据包/数据?
Is there any way for packets/data to be sent over the wire before the call to send() returns?
推荐答案
不,您的部分数据可能会通过网络传递,而另一部分数据仅会被复制到本地 TCP 堆栈的内部缓冲区中.send() 将返回编号.传递给本地 TCP 堆栈的字节数,而不是编号.传输到线路上的字节数(即使数据到达线路,也可能无法到达对等方).
No, it's possible that parts of your data gets passed over the wire, and another part only goes as far as being copied into the internal buffers of the local TCP stack. send() will return the no. of bytes passed to the local TCP stack, not the no. of bytes that gets passed onto the wire (and even if the data reaches the wire, it might not reach the peer).
或者有什么方法可以让操作系统在为系统调用提供服务时被中断,发送部分数据,等待可能很长时间,然后发送其余部分并返回而不用较小的返回值通知我?
因为 send() 只返回编号.传递到本地 TCP 堆栈的字节数,而不是 send() 是否实际发送任何内容,无论如何您无法真正区分这两种情况.但是,是的,可能只有一些数据通过网络传输.即使本地缓冲区中有足够的空间,对等方也可能没有足够的空间.如果你发送了 2 个字节,但对等方只有 1 个字节的空间,可能会发送 1 个字节,另一个将驻留在本地 tcp 堆栈中,直到对等方再次有足够的空间.
As send() only returns the no. of bytes passed into the local TCP stack, not whether send() actually sends anything, you can't really distinguish these two cases anyway. But yes, it's possibly only some data makes it over the wire. Even if there's enough space in the local buffer, the peer might not have enough space. If you send 2 bytes, but the peer only has room for 1 more byte, 1 byte might be sent, the other will reside in the local tcp stack until the peer has enough room again.
(这是一个极端的例子,大多数 TCP 堆栈都会防止一次发送如此小的数据段,但如果您尝试发送 4k 的数据而对等方只有 3k 的空间,则同样适用.
(That's an extreme example, most TCP stacks protects against sending such small segments of data at a time, but the same applies if you try to send 4k of data but the peer only have room for 3k).
我不是在谈论内核缓冲区空间不足的情况;我意识到我会得到一个较小的返回值并且必须再试一次
这只会发生在你的套接字是非阻塞的.如果它正在阻塞并且本地缓冲区已满,则 send() 将等待直到本地缓冲区中再次有空间(或者,它可能会返回如果部分数据已交付,但同时发生错误,则计数较短.)
That will only happen if your socket is non-blocking. If it's blocking and the local buffers are full, send() will wait until there's room in the local buffers again (or, it might returna short count if parts of the data was delivered, but an error occured in the mean time.)
编辑回答:
在调用 send() 返回之前,有没有办法通过线路发送数据包/数据?
是的.发生这种情况的原因有很多.例如
Yes. That might happen for many reasons.e.g.
- 本地缓冲区被最近的 send() 调用填满,并且您使用了阻塞 I/O.
- TCP 堆栈通过线路发送您的数据,但决定安排其他进程以在发送进程从 send() 返回之前运行.
这篇关于成功的 send() 是“原子的"吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!