我在TCP套接字上有关于send()的问题。
之间是否存在差异:
char *text="Hello world";
char buffer[150];
for(i=0;i<10;i++)
send(fd_client, text, strlen(text) );
和
char *text="Hello world";
char buffer[150];
buffer[0]='\0';
for(i=0;i<10;i++)
strcat(buffer, text);
send(fd_client, buffer, strlen(buffer) );
使用recv的接收方是否存在差异? 两者都是一个TCP数据包吗?
即使设置了TCP_NODELAY?
答案 0 :(得分:0)
真的没办法知道。取决于TCP的实施。如果它是一个UDP套接字,它们肯定会有不同的结果,你会在第一种情况下有几个数据包而在第二种情况下有一个数据包。
TCP可以随意拆分数据包;它模拟流并将其数据包机制抽象出用户。这是设计的。
答案 1 :(得分:0)
TCP是基于流的协议。如果运行Send,它会将一些数据放入OS TCP层缓冲区,OS会定期发送。但是如果你调用Send太快,它可能会在发送前一个数组之前将几个数组放入OS TCP层。所以就像堆栈一样,它会发送它所拥有的一切并将所有内容放在一个大数组中 通过OS TCP层进行分段来完成发送,并且还有Nagle算法可以防止在OS缓冲区足够大以满足一个段大小之前发送少量数据。
是的,有区别。
TCP是基于流的协议,您不能依赖单个发送将是具有相同数据量的单个接收 数据可能会合并在一起,您必须始终记住这一点。
顺便说一句,根据您的示例,在第一种情况下,客户端将一起接收所有字节或什么都不接收。同时,如果发送一个大段将在途中掉落,那么服务器操作系统将自动重新发送它。较大数据包的丢弃机会较高,因此重新发送大段会导致一些流量丢失。但这是基于丢弃数据包的百分比,可能根本不适用于您的情况。
在第二个示例中,您可能会收到所有内容或每个单独或部分合并的部分。您永远不会知道并且应该以这种方式实现网络读取,您知道您希望接收多少字节并只读取该字节数。这样,即使剩下一些未读字节,它们也会在下一个“读取”时被读取。