开发者

Using Boost.Asio to get "the whole packet"

开发者 https://www.devze.com 2023-01-02 06:04 出处:网络
I have a TCP client connecting to my server which is sending raw data packets. How, using Boost.Asio, can I get the \"whole\" packet every time (asynchronously, of course)? Assume these packets can be

I have a TCP client connecting to my server which is sending raw data packets. How, using Boost.Asio, can I get the "whole" packet every time (asynchronously, of course)? 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.


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

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


TCP doesn't operate with packets. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消