2010-06-06 22 views
2

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

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

回答

2

通常,当你做异步IO时,你的协议应该支持它。 一个简单的方法是在字节数组前加一个长度为逻辑级的字节数组,并使读取代码缓冲区一直存在,直到它有一个完整的缓冲区准备好解析。如果你不这样做,那么你最终会把这个逻辑分散到所有的地方(想想阅读一个以空字符结尾的字符串,以及如果你每次选择/轮询都得到它的一部分,这意味着什么回报)。

+0

哈哈,这实际上已经完成 - 我想知道为什么有一个包头!我认为这一切都是由TCP协议处理 - 猜我错了。 – 2010-06-06 17:12:16

+0

是的,正如jalf提到的 - tcp向应用程序呈现流,而不是数据包。所以你需要从逻辑上分离你的数据包。 – 2010-06-06 17:14:00

3

TCP不使用数据包。它为您提供了一个连续的流。您可以询问接下来的N个字节,或者对于迄今为止收到的所有数据,但没有“数据包”边界,无法区分什么是或不是数据包。

+0

然后什么是wireshark显示? – 2010-06-06 17:05:21

+1

底层数据包。 TCP是在基于数据包的IP协议之上实现的。但是这些数据包是内部实现细节。他们没有被应用程序看到。 – jalf 2010-06-06 17:19:03

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

这是标准RFC1006 – hplbsh 2011-08-24 17:54:52