有效载荷分割在两个TCP数据包使用Boost ASIO时,当它适合的MTU内 [英] Payload split over two TCP packets when using Boost ASIO, when it fits within the MTU

查看:240
本文介绍了有效载荷分割在两个TCP数据包使用Boost ASIO时,当它适合的MTU内的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个boost :: ASIO ::知识产权:: TCP :: iostream的一个问题。我想送约20原始字​​节。的问题是,这20字节的有效负载被分成两个TCP数据包与1个字节,然后19个字节。简单的问题,为什么会发生,我不知道。我是一个传统的二进制协议,非常需要有效载荷,以适应在一个TCP数据包(呻吟声)写的。

I have a problem with a boost::asio::ip::tcp::iostream. I am trying to send about 20 raw bytes. The problem is that this 20 byte payload is split into two TCP packets with 1 byte, then 19 bytes. Simple problem, why it is happening I have no idea. I am writing this for a legacy binary protocol that very much requires the payload to fit in a single TCP packet (groan).

粘贴整个源从我的程序将是长期的和过于复杂,我已经张贴功能问题,这里只是在2个功能(经测试,它重现该问题);

Pasting the whole source from my program would be long and overly complex, I've posted the functional issue just within 2 functions here (tested, it does reproduce the issue);

#include <iostream>

// BEGIN cygwin nastyness
// The following macros and conditions are to address a Boost compile
// issue on cygwin. https://svn.boost.org/trac/boost/ticket/4816
//
/// 1st issue
#include <boost/asio/detail/pipe_select_interrupter.hpp>

/// 2nd issue
#ifdef __CYGWIN__
#include <termios.h>
#ifdef cfgetospeed
#define __cfgetospeed__impl(tp) cfgetospeed(tp)
#undef cfgetospeed
inline speed_t cfgetospeed(const struct termios *tp)
{
    return __cfgetospeed__impl(tp);
}
#undef __cfgetospeed__impl
#endif /// cfgetospeed is a macro

/// 3rd issue
#undef __CYGWIN__
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
#define __CYGWIN__
#endif
// END cygwin nastyness.

#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <iostream>

typedef boost::asio::ip::tcp::iostream networkStream;

void writeTestingData(networkStream* out) {
        *out << "Hello world." << std::flush;
//      *out << (char) 0x1 << (char) 0x2 << (char) 0x3 << std::flush;
}

int main() {
        networkStream out("192.168.1.1", "502");

        assert(out.good());

        writeTestingData(&out);
        out.close();
}

要添加到奇怪的问题,如果我发送字符串Hello World,它会在一个包中。如果我送为0x1,0X2,0x3中(原始字节值),我得到了包1为0x1,那么数据在接下来的TCP数据包的其余部分。我使用Wireshark来看看数据包,只有在开发机和192.168.1.1之间的开关。

To add to the strange issue, if I send the string "Hello world.", it goes in one packet. If I send 0x1, 0x2, 0x3 (the raw byte values), I get 0x1 in packet 1, then the rest of the data in the next TCP packet. I am using wireshark to look at the packets, there is only a switch between the dev machine and 192.168.1.1.

推荐答案

您code:

out << (char) 0x1 << (char) 0x2 << (char) 0x3;

将使3个电话运营商的LT;&LT; 函数

由于TCP的 Nagle算法的,TCP堆栈将发送数据资料((字符)为0x1)来后,立即对等体/第一运营商的LT期间;&LT; 电话。
所以数据(0X2和0x3中)的其余部分将进入下一个数据包。

Because of Nagle's algorithm of TCP, TCP stack will send available data ((char)0x1) to peer immediately after/during the first operator<< call. So the rest of the data (0x2 and 0x3) will go to the next packet.

解决方案,以避免1个字节TCP段:
调用具有更大的一堆数据发送功能。

Solution for avoiding 1 byte TCP segments: Call sending functions with bigger bunch of data.

这篇关于有效载荷分割在两个TCP数据包使用Boost ASIO时,当它适合的MTU内的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆