【问题标题】:recv function gives malformed data Winsock2 C++recv 函数给出格式错误的数据 Winsock2 C++
【发布时间】:2014-02-27 16:20:15
【问题描述】:

在我的简单 TCP 客户端服务器应用程序中,服务器重复向客户端发送 1 kB 消息,客户端为每个数据包发送回复确认(仅发送“ACK”)。试想一下这种情况就像客户端和服务器在无限循环中到处传递 1 kB 消息。

我每次发送相同的消息,第一个字节(第一个字符)始终为 1。但是在同一台机器上长时间测试这个客户端和服务器应用程序时,我注意到一些接收到的消息的第一个字符是接收缓冲区中的其他内容和recv 函数也返回了 1024 (1 kB)。这种情况并不经常发生。

这就是我收到的方式。

char recvBuff[DEFAULT_BUFFER_SIZE];
int iResult = SOCKET_ERROR;
iResult = recv(curSocket, recvBuff, DEFAULT_BUFFER_SIZE, 0);
if (iResult == SOCKET_ERROR)
{
   return iResult;
}

if (recvBuff[0] != 1)
{
   //malformed receive
}

MessageHeader *q = (MessageHeader*)recvBuff;
message.header = *q; q++;
std::string temp((char*)q, message.header.fragmentSize);
message.message = temp;

实际上问题在于构建临时字符串。由于未收到正确的片段大小,它会中断。我试图删除这些格式错误的数据。但问题是最后一次成功接收的分片 ID 和格式错误接收后第一次成功收到的分片 ID 之间存在差距。知道为什么会发生这些格式错误的接收吗?

【问题讨论】:

    标签: tcp recv malformed


    【解决方案1】:

    您假设您在 recv() 呼叫完成时收到了完整的消息。如果这是一个 TCP 连接(相对于 UDP),它是面向字节的,这意味着recv() 将返回只要有任何字节可用

    更明确地说,没有理由这样做

    send (toServerSocket, someMessage, 1024, 0);
    

    在客户端会导致

    recv (fromClientSocket, myBuffer, 1024, 0);
    

    接收 1,024 个字节。它也可以接收 27 个字节,其余 997 个来自未来对recv() 的调用。

    那么,您的程序中发生的情况是,您获得了这些短期回报之一,这导致您的程序失去同步。与消息流。如何解决?使用recv() 阅读足够多的消息以了解长度(或设置固定长度,尽管在许多情况下效率低下)。然后继续将recv() 调用到缓冲区中,直到您至少读取了那么多字节。 请注意,您可能会读取比消息长度更多的字节——也就是说,您可能会读取一些属于 下一个消息的字节,因此您需要保留这些字节处理当前消息后在缓冲区中。

    【讨论】:

    • 嗯.. 看来你是对的。我知道sendrecv 不能保证完整的发送和接收。但我认为 1024 字节将是完全发送和接收的可能大小。好像是我错了。是的,会发生什么。这就是我丢失邮件标题的原因。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 2013-06-08
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多