简体   繁体   English

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

[英]Using Boost.Asio to get “the whole packet”

I have a TCP client connecting to my server which is sending raw data packets. 我有一个连接到我的服务器的TCP客户端,它正在发送原始数据包。 How, using Boost.Asio, can I get the "whole" packet every time (asynchronously, of course)? 如何使用Boost.Asio,每次都可以得到“整个”数据包(当然是异步的)? Assume these packets can be any size up to the full size of my memory. 假设这些数据包可以是任何大小,直到我的内存的完整大小。

Basically, I want to avoid creating a statically sized buffer. 基本上,我想避免创建一个静态大小的缓冲区。

TCP doesn't operate with packets. TCP不与数据包一起运行。 It provides you one contiguous stream. 它为您提供了一个连续的流。 You can ask for the next N bytes, or for all the data received so far, but there is no "packet" boundary, no way to distinguish what is or is not a packet. 您可以要求接下来的N个字节,或者到目前为止收到的所有数据,但是没有“数据包”边界,无法区分什么是或不是数据包。

Typically when you build a custom protocol on the top of TCP/IP you use a simple message format where first 4 bytes is an unsigned integer containing the message length and the rest is the message data. 通常,当您在TCP / IP顶部构建自定义协议时,您使用简单的消息格式,其中前4个字节是包含消息长度的无符号整数,其余是消息数据。 If you have such a protocol then the reception loop is as simple as below (not sure what is ASIO notation, so it's just an idea) 如果你有这样的协议,那么接收循环就像下面那样简单(不确定什么是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
  ...
}

typically, when you do async IO, your protocol should support it. 通常,当您执行异步IO时,您的协议应该支持它。 one easy way is to prefix a byte array with it's length at the logical level, and have the reading code buffer up until it has a full buffer ready for parsing. 一种简单的方法是在逻辑级别为字节数组添加它的长度前缀,并使读取代码缓冲,直到它有一个完整的缓冲区准备好进行解析。

if you don't do it, you will end up with this logic scattered all over the place (think about reading a null terminated string, and what it means if you just get a part of it every time select/poll returns). 如果你不这样做,你最终会把这个逻辑分散到各处(考虑读取一个空终止的字符串,如果你只是在每次select / poll返回时得到它的一部分意味着什么)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM