0

In my simple TCP client server application, server send repetitively 1 kB message to the client and client send a reply acknowledgement (just send 'ACK') for each packet. Just think this scenario like client and server passing 1 kB messages here and there in a infinite loop.

I send the same message every time and the fist byte (first char) is always 1. But while testing this client and server application in the same machine for a long time, I noticed first character of some of the received messages are something else in the receive buffer and recv function also returned 1024 (1 kB). This is not happen frequently.

This is the how I receive.

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;

Actually the problem is in constructing the temp string. It breaks since the correct fragment size not received. I tried to drop these kind of malformed data. But the problem is there is a gap between last successfully received fragment ID and first successfully received fragment ID after malformed receives. Any idea why these malformed receives happen?

4

1 回答 1

1

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

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

send (toServerSocket, someMessage, 1024, 0);

在客户端会导致

recv (fromClientSocket, myBuffer, 1024, 0);

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

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

于 2014-02-27T08:13:41.070 回答