使用Boost.Asio获取“整个数据包”

时间:2010-06-06 16:54:57

标签: c++ networking boost boost-asio

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

基本上,我想避免创建一个静态大小的缓冲区。

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

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

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
  ...
}

答案 2 :(得分:2)

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

如果你不这样做,你最终会把这个逻辑分散到各处(考虑读取一个空终止的字符串,以及如果你每次选择/轮询返回时只是获取它的一部分意味着什么)。