包含消息长度的两个字节标头上的部分recv()呢?
What about partial recv() on two byte header containing message length?
我一直在阅读一些插座指南,例如Beej的网络编程指南。现在很明显,在单个recv()呼叫中收到多少个字节可以保证。因此,例如前两个字节说明消息长度应发送,然后发送消息。因此,接收器接收前两个字节,然后在循环中接收到整个消息。一切都很好,花花公子!?
我被一位同事询问我的消息。例如。如果某种程度上,我在一次recv()呼叫中收到两个字节,这些字节实际上位于消息本身的中间,并且它将看起来像某种值的整数?这是否意味着发送的其余数据将不同步?那部分接收标头,即一次字节呢?
也许这是过度思考的,但是我在任何地方都找不到这一点,我只想确定,如果这可能是对通信完整性的威胁,我会处理这一点。
谢谢。
它不会过度思考。TCP呈现流,因此您应该以这种方式对待。有关TCP的许多问题是由于网络问题引起的,并且可能不会在开发过程中发生。
用(4个字节)魔术启动一条消息,您可以在预期顺序(通常是大的endian)中查找(4个字节)长度。接收时,当时读取标题的每个字节,因此您可以将其处理。基于此,您可以在持久的TCP连接中接受消息。
请注意,每条消息启动新连接时,您就会知道起点。但是,如果只是要滤除一些无效的消息,也不会伤害发送魔术。
不需要校验和,因为TCP显示了一个可靠的字节,该字节已由TCP的接收部分检查,并且仅在发送/接收的编码问题时才需要同步。
另一方面,UDP发送数据包,因此您知道会发生什么,但是不能保证交货和订单。
您的同事错误。TCP数据无法订购。但是,您应该将MSG_WAITALL标志调查到recv()
,以克服两个长度字节分别到达的可能性,并在接收消息主体时消除循环的需求。
您有责任使您的客户端和服务器共同同步,在TCP中没有订单交付,如果您通过调用recv()获得某些东西,您可以认为有东西'您没有收到的任何东西。
所以问题是如何同步发送者和接收器?正如Stefaanv所说,它很容易,发件人和接收者知道他们的起点。因此,您可以为网络通信定义协议。例如,可以这样定义协议:
4个字节,包括消息类型和有效载荷长度
消息的其余部分是有效载荷长度
这样,您必须在发送实际有效载荷之前发送4个字节标头,然后发送实际有效载荷。
由于TCP已使用订单可靠交付,因此您可以为每个包进行两个recv()调用。一个recv()调用,长度为4个字节,用于获取下一个有效载荷大小,另一个调用reacv()在标题中指定的大小。这是使recv()阻止以始终进行同步所必需的。
一个例子就是这样:
#define MAX_BUF_SIZE 1024 // something you know
char buf[MAX_BUF_SIZE];
int recvLen = recv(fd, buff, 4, MSG_PEEK);
if(recvLen==4){
recvLen = recv(fd, buff, 4);
if(recvLen != 4){
// fatal error
}
int payloadLen = extractPayloadLenFromHeader(buf);
recvLen = recv(fd, buff, payloadLen, MSG_PEEK);
if(recvLen == payloadLen){
recvLen = recv(fd, buff, payloadLen); // actual recv
if(recvLen != payloadLen){
// fatal error
}
// do something with received payload
}
}
您可以看到,我首先将带有msg_peek标志的RECV调用,以确保实际上是否有4个字节,然后收到了实际标题。有效载荷
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 如何返回一个类的两个对象相加的结果
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 两个字符串在 c++ 中不相等
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 两个文件使用彼此的功能-如何解决
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 将fold表达式与std::一起用于两个元组
- 如何在C++中比较两个char数组
- 给定两个偶数,求出它们之间所有偶数的平方和
- 比较两个大小不等的映射c++
- C++需要帮助从用户那里获得一个整数,并确保它在另外两个整数之间
- 如何在for循环中包含两个索引值的测试条件
- 在声明中合并两个常量"std::set"(不是在运行时)
- 包含消息长度的两个字节标头上的部分recv()呢?