recv()直到收到NUL字节?

kil*_*ode 4 c sockets winsockets

我正在尝试一次从服务器接收单个数据包,因为数据包的运行速度太快,并且每个数据包的大小都未定义,因此调用带有读取字节数的recv()会读取第一个数据包,也许是其中的一部分第二个数据包。由于每个数据包都以NULL终止,因此我想逐字节读取直到接收到NULL字节。

    int recvLen = 0;
    char TB;
    char recvBuffer[1024];
    while (recv(Socket, &TB, 1, 0) > 0 && TB != 0 && recvLen < 1024)
    {
        recvBuffer[recvLen] = TB;
        recvLen++;
    }
Run Code Online (Sandbox Code Playgroud)

我认为这种方法根本无效。如果服务器发送了1024个字节,recv()将被调用1024次。

在接收到NULL字符之前,是否还有其他方法可以调用recv(),或者有比我正在使用的方法更好的方法?


编辑:我在从服务器发送的数据的前面添加了数据包大小,但是现在,如果一个错误的数据包甚至有时无缘无故,数据包就会混乱,并且无法接收到正确的数据。这是我的代码

#define UPLOAD_LEN 2755
int PacketSize, recvLen;
char Size[4];
char recvBuffer[UPLOAD_LEN+1];
while(1)
{
    if(recv(Socket,Size,4,0)>0)
    {
        Size[4] = '\0';
        PacketSize = atoi(Size);
        if (PacketSize > UPLOAD_LEN || PacketSize <= 0) continue;
        recvLen = recv(Socket, recvBuffer, PacketSize, 0);
    } else recvLen = -1;
    if (recvLen > 0)
    {
        recvBuffer[recvLen] = '\0';
        ProcessData(recvBuffer);
    }
    else
    {
        closesocket(Socket);
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*cke 5

我从未理解过,为什么通信协议永远不支持程序员希望能够实现的一种用例:用边界对齐的send和recv交换任意大小的Blob。

因此,这里没有真正的捷径。您需要保留一个持久缓冲区,该缓冲区保存上次调用recv时剩余的所有数据。不断在接收到数据时将数据添加到末尾,并且每次找到一个数据时都返回到终止的零。您可能至少会有一部分后续数据包,因此请将其移至缓冲区的开头,以作为下一次调用的初始状态。