假设我在服务器上拨打了 3 次电话send
send(sock,"I",sizeof("I"),0);
send(sock,"Y",sizeof("Y"),0);
send(sock,"X",sizeof("X"),0);
在客户端,我打了 3 次电话recv
recv(sock,buf,sizeof(buf),0);
recv(sock,buf,sizeof(buf),0);
recv(sock,buf,sizeof(buf),0);
有时会发生三个 send 调用的执行速度比数据到达客户端的速度要快,所以第一个 recv 调用读取了三个 send 调用发送的所有数据,而第二个 recv 在预期中冻结,你必须做“安全网”:
客户端收到第一次send调用的数据,然后向服务器发送一个肯定响应,服务器上的下一个send调用只有在收到客户端的肯定响应后才执行,这非常集体农场,所以如果你知道一个正常的方式 - 写一个答案
从编程的角度来看,TCP 表示双向数据流,并且该数据可以一次以任意块的形式传送,可以更小也可以更大。您需要使用您的协议将此流划分为消息,该协议在 TCP 之上运行。
主要有几种方式:
发送和阅读固定长度的消息。
接待:
使用分隔符/字符串。
接待:
在它之前/在其标题中发送消息大小。
接待:
每个连接只发送一条消息。
接待:
所有方法都可以以各种组合使用,每种方法都有优点和缺点。例如,(1)只适用于非常简单的协议,实际上在示例(3)中也用于“header”;HTTP 对标头使用方法 (2),对内容使用方法 (3),或者在旧版本中使用方法 (4)。
您还应该记住,一次可以不仅更多,而且更少数据,因此上面的示例使用 MSG_WAITALL 或带缓冲的完整读取周期,如 (2) 和 (4) 所示。就本地系统的开销而言,类似的用户空间读取循环通常也适用于其他选项。对于服务于许多客户端的服务器的情况,通常需要它。
免责声明:所有代码都是推测性地编写以说明原理,不会调试,并且可能包含错误。