使用 recv() 接收消息块

Using recv() to receive chunks of a message

我正在使用 WebSockets。我创建了一个小型测试客户端,它将消息拆分,然后逐块发送。例如这样的消息:

PROTOCOL HTTP ACTION UPDATE

可以发送为

PROTOC

然后作为一个块

OL HTT

作为另一个而不是在一个块中发送完整的消息作为 PROTOCOL HTTP ACTION UPDATE 这也是一种可能性。

所以我接收消息的方式必须反映这一点。目前,我不确定如何使用 recv 当一条消息被分成多个部分并发送时。

这就是我正在尝试的方法,但我不确定这是否是正确的方法。我应该在接收时始终将缓冲区的大小保持为 200 吗?我应该什么时候退出循环?

void recv_all(){
            char rec_buffer[200]
            while(1) {
              ssize_t bytes_rec = recv(socket_fd, rec_buffer, sizeof(rec_buffer),0);

            }
}

您可以使用调用 read() 的返回值,然后使用 strcat() 将消息的各个部分粘合在一起。

根据 OP,消息以 \r\n 结尾,这是一个如何将消息作为多个数据包读取的示例。

char *message = malloc( MAX_MSG_LEN +1 );
if( ! message )
{
    perror( "malloc failed" );
    exit( EXIT_FAILURE );
}

// implied else, malloc successful

recv_buf[0] = '[=10=]';
size_t msgLen = 0;
int done = 0;

while( msgLen < MAX_MSG_LEN && !done)
{
    ssize_t byteCount = read( socket_fd, message, MAX_MSG_LEN );

    if( ! byteCount )
    {
        // handle error of sender closing the socket
    }

    else if( byteCount < 0 )
    {
        // handle I/O error
    }

    else
    {
        if( msgLen+byteCount > sizeof( recv_buf ) )
        {
            // handle error of message too long
        }

        else
        {
            message[ byteCount ] = '[=10=]';
            strcat( recv_buf, message );
            msgLen += byteCount;
            if( memcmp( recv_buf[msgLen-2], "\r\n", 2 ) == 0 )
            {
                 done = 1;
            }
        }
    }
}
free( message );

注意:我没有运行上面的例子,所以可能需要做一些调试。

(stream) 套接字处理字节流,而不是消息。因此,它们提供了一种在端点之间获取字节流的方法,仅此而已。如果您想要某种 'messages',您需要处理字节流以找到消息边界并自行将其分解为消息。

执行此操作的通常方法是使用缓冲区,例如 C FILE 对象或 C++ streambuf。您安排字节从套接字读取到缓冲区,然后检查缓冲区中是否有完整的消息,通常是通过查找消息 terminator/boundary 标记(例如 \r\n 或只是 \ n).如果存在,则(仅)从缓冲区中删除消息。

在 C 语言中使用 POSIX 很容易做到——您可以使用 fdopen 打开一个带有套接字描述符的文件,然后使用 fgets 或 getline 读取消息直到换行符.