C++ 使用Boost.Asio获取;“整包”;

C++ 使用Boost.Asio获取;“整包”;,c++,networking,boost,boost-asio,C++,Networking,Boost,Boost Asio,我有一个TCP客户端连接到正在发送原始数据包的服务器。如何使用Boost.Asio每次(当然是异步的)获取“整个”数据包?假设这些数据包的大小可以达到我的全部内存大小 基本上,我希望避免创建静态大小的缓冲区。TCP不处理数据包。它为您提供一个连续的流。您可以请求接下来的N个字节,或者请求到目前为止接收到的所有数据,但是没有“数据包”边界,无法区分什么是数据包或什么不是数据包。通常,当您执行异步IO时,您的协议应该支持它。 一种简单的方法是在逻辑级别用字节数组的长度作为前缀,并使读取代码缓冲区处于

我有一个TCP客户端连接到正在发送原始数据包的服务器。如何使用Boost.Asio每次(当然是异步的)获取“整个”数据包?假设这些数据包的大小可以达到我的全部内存大小


基本上,我希望避免创建静态大小的缓冲区。

TCP不处理数据包。它为您提供一个连续的流。您可以请求接下来的N个字节,或者请求到目前为止接收到的所有数据,但是没有“数据包”边界,无法区分什么是数据包或什么不是数据包。

通常,当您执行异步IO时,您的协议应该支持它。 一种简单的方法是在逻辑级别用字节数组的长度作为前缀,并使读取代码缓冲区处于上升状态,直到它有一个完整的缓冲区准备进行解析


如果您不这样做,那么最终将导致该逻辑分散在各个地方(请考虑读取以null结尾的字符串,以及如果您每次返回select/poll时只获取其中的一部分,这意味着什么).

通常,在TCP/IP之上构建自定义协议时,使用简单的消息格式,其中前4个字节是包含消息长度的无符号整数,其余为消息数据。如果您有这样一个协议,那么接收循环如下所示(不确定ASIO表示法是什么,所以这只是一个想法)

(;;)的
{
uint_32_t len=0u;
read(socket,&len,4);//在非阻塞模式下可能需要多次读取
len=ntohl(len);
断言(len
哈哈,这实际上已经完成了-我想知道为什么会有一个包头!我认为这一切都是由TCP协议处理的——我猜我错了。是的,正如jalf提到的——TCP向应用程序提供了一个流,而不是数据包。因此,您需要在逻辑上分离数据包。底层数据包。TCP是在基于数据包的IP协议之上实现的。但这些数据包是一个内部实现细节。应用程序看不到它们。
for(;;) {
  uint_32_t len = 0u;
  read(socket, &len, 4); // may need multiple reads in non-blocking mode
  len = ntohl(len);
  assert (len < my_max_len);
  char* buf = new char[len];
  read(socket, buf, len); // may need multiple reads in non-blocking mode
  ...
}