我从互联网上获得了一个片段,用于通过套接字发送数据。
这是代码。
u32_t nLength = 0;
u32_t nOffset = 0;
do {
nLength = nFullLength - nOffset;
status = Socket->Send(((u8_t*) buff) + nOffset, &nLength);
if (status != ERROR_SUCCESS) {
break;
}
nOffset += nLength;
} while (nOffset < nFullLength);
我的怀疑是:
当send(sock_fd, buf+bytes, buflen-bytes, flags);
函数运行时,它会发送整个数据吗?
假设我有buff
45 byte length
。所以它会像
send(buf+0, 45-0) = send(buf+0, 45);
那么它会发送长度为45的完整数据吗?这里的长度有什么用?最初会45。不是吗?
答案 0 :(得分:1)
嗯,不。我们无法保证它会发送您要求它发送的所有数据,这就是代码看起来如此的原因。
send()
的手册页明确说明了这一点:
返回值
成功时,这些调用将返回发送的字符数。出错,-1 返回,
errno
设置正确。
对于例如同样如此顺便说一句,定期write()
到本地文件。它可能永远不会发生,但是接口设计的方式是你应该处理部分发送(和写入),如果它们发生的话。
答案 1 :(得分:1)
TCP是一种流式传输。无法保证给定的send()
操作将同时接受给它的所有字节。它取决于可用的内核缓冲区空间,套接字的I / O模式(阻塞与非阻塞)等。send()
返回它实际接受并放入内核缓冲区以供后续传输的字节数。
在显示的代码示例中,似乎Socket->Send()
期望nLength
最初设置为要发送的总字节数,然后它将更新nLength
的数量为字节实际发送。代码正在相应地调整其nOffset
变量,循环以防万一 send()
返回的字节数少于请求的字节数,因此它可以调用send()
所需的次数。发送完整的字节数。
因此,例如,假设内核一次最多接受20个字节。循环将调用send()
3次:
send(buf+0, 45-0) // returns 20
send(buf+20, 45-20) // returns 20
send(buf+40, 45-40) // returns 5
// done
这是TCP编程的典型编码实践,考虑到TCP的流媒体特性。