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

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

问题描述

我有一个问题与boost :: asio :: ip :: 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(原始字节值),我得到0x1在数据包1,然后剩下的数据在下一个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.

推荐答案

代码:

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

将会调用运算符 > function。

Will make 3 calls of operator<< function.

由于 Nagle的算法的TCP ,TCP堆栈将在第一个运算符之前/期间立即发送可用数据((char)0x1) >调用。
其余数据(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段的解决方案:
Call发送具有更大数据集的函数。

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

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

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