c++ - 从套接字接收前几个字节以确定缓冲区大小

标签 c++ sockets network-programming

我正在用 c++ 使用 TCP/IPsockets 编写一个分布式系统。

对于我的每条消息,我需要接收前 5 个字节才能知道传入消息的完整长度。

执行此操作的最佳方法是什么?

  1. recv() 只有 5 个字节,然后再次 recv()。如果我选择这个,假设我会在 recv 中得到 0 或 5 个字节(也就是不写一个循环来继续尝试)是否安全?
  2. 使用MSG_PEEK
  3. recv() 一些较大的缓冲区大小,然后读取前 5 个字节并分配最终缓冲区。

最佳答案

不需要知道任何事情。 TCP 是一种流协议(protocol),在任何给定时刻,您可以获得少至一个字节或多至数兆字节的数据。使用 TCP 套接字的正确且唯一的方法是循环读取。

char buf[4096];        // or whatever

std::deque<char> data;

for (int res ; ; )
{
    res = recv(fd, buf, sizeof buf, MSG_DONTWAIT);

    if (res == -1)
    {
        if (errno == EAGAIN || errno == EWOULDBLOCK)
        {
            break;  // done reading
        }
        else
        {
            // error, break, die
        }
    }
    if (res == 0)
    {
        // socket closed, finalise, break
    }
    else
    {
        data.insert(data.end(), buf, buf + res);
    }
}

循环的唯一目的是将数据从套接字缓冲区传输到您的应用程序。然后,您的应用程序必须独立地决定队列中是否有足够的数据来尝试提取某种更高级别的应用程序消息。

例如,在您的情况下,您将检查队列的大小是否至少为 5,然后检查前五个字节,然后检查队列是否包含完整的应用程序消息。如果否,则中止;如果是,则提取整个消息并从队列的前面弹出。

关于c++ - 从套接字接收前几个字节以确定缓冲区大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12408738/

相关文章:

在 EPIPE 之后关闭套接字文件描述符

java - 通过单个套接字进行多个 HTTP POST

http - TCPCatcher : send HTTP request from hook

c++ - C++中的 "a<?=b"是什么意思?

c++ - 如何获得指向编译器选择的重载函数的函数指针?

c - inet_ntop 始终返回相同的 IP

java - 如何复用DatagramSocket?

linux - netcat 能否以直通方式工作

c++ - WebRTC AGC(自动增益控制)

c++ - C++-标准输入循环