2

我有一个 tcp 客户端需要通过 tcp 读取数据,但我每次都需要读取一个 tcp 数据包数据。

我使用这个代码:

        socket_[socket_index]->async_receive(
            boost::asio::buffer(buf, max_size),
            boost::bind(
              &pipe::handle_read, shared_from_this(),
              boost::asio::placeholders::error,
              socket_index,
              boost::asio::placeholders::bytes_transferred));

但有时我读取了多个数据包。我需要将其更改为仅读取一个数据包数据吗?

4

3 回答 3

3

你就是不能。您对网络概念感到困惑,TCP 比这更高级别。

如果您确实需要处理单个数据包,请使用 UDP。对于您的最小情况,很容易切换。

于 2012-05-07T16:45:53.423 回答
1

TCP 不是面向数据包的——它的数据流。数据包可以在任何一侧合并在一起,依此类推。我使用以下技术来读取数据包:

async_read(sock, asio::buffer(buf, sizeof(packet_header)), ...

例如,只读数据包阅读器。现在,我在异步读取处理程序中拥有完整的逻辑数据包长度,所以我可以asio::read准确地读取字节数来读取其余的逻辑数据包;然后async_read再次设置以等待下一个数据包头。

如果您的标头中没有逻辑数据包长度,则无法检测逻辑数据包的结束位置(在 TCP 情况下)。

于 2012-09-23T05:50:29.633 回答
0

在实践中控制的方式是传递您想要读取的字节数而不是缓冲区的大小。

您可以将数据包中的字节数放在数据包标头中的标准偏移量中。首先读取包头的大小。然后取数据包中的字节数(减去数据包头的大小)并读取那么多字节。

或者,继续让它读取多个数据包。处理该数据包。处理完第一个数据包后,判断是否读取了多个数据包,如果是,则将其 memcpy 到数据包缓冲区的开头。如果缓冲区中有一个完整的数据包,请处理,如果没有,请在 memcpy 结束的末尾阅读更多内容。

于 2012-05-08T20:55:44.857 回答