代码之家  ›  专栏  ›  技术社区  ›  Clark Gaebel

使用boost.asio获取“整个包”

  •  2
  • Clark Gaebel  · 技术社区  · 15 年前

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

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

    3 回复  |  直到 12 年前
        1
  •  2
  •   Omry Yadan    15 年前

    通常,当您执行异步IO时,您的协议应该支持它。 一种简单的方法是在逻辑级别为字节数组加前缀,并将读取代码缓冲区设置为最大,直到有一个完整的缓冲区可以解析为止。

    如果您不这样做,您将最终得到散布在各处的逻辑(考虑读取以空结尾的字符串,如果每次select/poll返回时只获取其中的一部分,这意味着什么)。

        2
  •  3
  •   Stack Overflow is garbage    15 年前

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

        3
  •  3
  •   bobah    12 年前

    通常,当您在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
      ...
    }