- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我对 boost::asio::ip::tcp::iostream 有疑问。我正在尝试发送大约 20 个原始字节。问题是这个 20 字节的有效载荷被分成两个 TCP 数据包,先是 1 字节,然后是 19 字节。简单的问题,为什么会发生我不知道。我正在为遗留二进制协议(protocol)编写此代码,该协议(protocol)非常需要有效负载适合单个 TCP 数据包(呻吟)。
从我的程序中粘贴整个源代码会很长而且过于复杂,我已经在此处的 2 个函数中发布了功能问题(经过测试,它确实重现了该问题);
#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 之间只有一个开关。
最佳答案
别担心,您是唯一一个遇到此问题的人。肯定有解决办法。事实上,您的遗留协议(protocol)有两个问题,而且不止一个。
您的旧遗留协议(protocol)需要一个“应用程序消息”以适应“一个且只有一个 TCP 数据包”(因为它错误地将面向 TCP 流的协议(protocol)用作面向数据包的协议(protocol))。所以我们必须确保:
解决方案:
您必须立即将所有“消息”数据提供给您的套接字。这目前没有发生,因为正如其他人所概述的那样,当您使用连续的“<<”并且您的操作系统的底层 TCP/IP 堆栈不缓冲时,您使用的 boost 流 API 将数据放入单独调用的套接字中足够了(并且有理由,为了更好的性能)
多种解决方案:
您必须激活 TCP_NODELAY socket 上的选项。此选项专为此类遗留协议(protocol)案例而设计。它将确保操作系统 TCP/IP 堆栈“毫不延迟地”发送您的数据,并且不会将其与您稍后可能发送的其他应用程序消息一起缓冲。
如果你解决了这两个问题,你应该没问题!
Windows 或 Linux 上的操作系统套接字 API 使用起来有点棘手,但您将获得对其行为的完全控制。 Unix example
关于c++ - 当使用 Boost ASIO 时,有效载荷在 MTU 范围内拆分为两个 TCP 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6846924/
获取 MTU 大小值的 POSIX 函数是什么??谢谢。 最佳答案 不,没有通用的 POSIX 函数。您可以做的最好的事情是在套接字上调用 GET_MTU/SIOCGIFMTU ioctl,但这不在
我是 BLE 开发的新手。我想通过 BLE 连接以最大吞吐量发送大量数据。 我有一个在 Linux 上运行的 GATT 服务器,以及一个在 Android 上作为应用程序运行的客户端。我创建了一个具有
我想通过ifconfig docker0 mtu 1400将docker0 mtu修改为1400,并且成功。 但过了一会儿,MTU回到1500。请帮忙,如何在我的K8S集群中修改docker0。 最佳
我是一名新手,正在尝试一些网络编程。我正在通过多播读取数据(请参见下面的代码),并且想要找到最大传输单元(MTU)或我可以读取的传输单元。任何人都可以指导我找到来源或方法来做到这一点。谢谢。 tr
我想知道是否有任何方法可以调整(在 Linux 系统上)给定套接字的 MTU。 (使 IP 层分段成比实际设备 MTU 更小的 block )。 当我说对于给定的套接字时,我并不是指在拥有套接字的应用
ifconfig 1.2.3.4 mtu 1492 这会将传入、传出数据包或两者的 MTU 设置为 1492?我认为它仅适用于传入 最佳答案 TLDR:两者都有。它只会传输有效载荷长度小于或等于该大小
我用 BluetoothGatt.requestMtu(512)在我的安卓应用程序中。 第一次效果很好 但是在 Mtu 自动更改为 23 之后(默认) 我不知道是什么问题... 这是一个日志 `D/B
我正在开发与 BLE 设备通信的应用程序。我可以轻松地在特征上写 20 个字节,但是当它超过 20 个字节时就会产生问题。我正在使用 mBluetoothGatt.requestMtu(512); 成
我的手机在向网络发送数据时出现问题。我认为我必须更改其 MTU 大小才能使其正常工作。 最佳答案 要更改 MTU 设置,您需要对手机进行 Root。在论坛中搜索如何操作。之后你需要安装一个终端模拟器并
我在 iOS 7 中使用 CoreBluetooth,并成功地让两台设备在彼此之间发送大量数据(一个是中央设备,一个是外围设备)。 在 iPhone 5 和 4S 之间我有一个 20 字节的 MTU,
我需要将 MTU 永久更改为 1500。我所说的永久是指如果我重新启动系统或将执行 service network restart,它将始终为 1500。 我关注了这篇文章http://www.cyb
如何找到连接之间的路径 MTU?我需要它来定义我的 UDP 连接的数据包大小。 .Net 中有 Path MTU Discovery 之类的东西吗? 最佳答案 我找到了一种方法(解决方法)来在 C#
我正在开发一个应用程序,我需要在多个 UDP 数据包中向客户端发送大量数据,我如何以编程方式确定我的 UDP 套接字的 MTU? 我需要能够在 Windows 和 Linux 上执行此操作。 最佳答案
对智能手机上 BLE 的参数进行一些跨平台研究。 我有 iOS 设备,因此嗅探了适用于 iOS 的 ATT_Exchange_MTU_Req/Rsp。 有没有人为 Android 做过同样的事情并获得
写入器程序使用固定缓冲区的多次写入发送几 MB(几乎没有延迟)。处理程序在 EPOLLOUT | 中注册。 EPOLLET 标志。 MTU=16KB,写入缓冲区 = 4KB 或更多。 write(..
我的 RAW-Socket 有一个小问题。我必须捕获网络中的数据包才能修改它们。为此,我必须添加特殊数据,例如时间戳。一切正常,但我的 MTU (Linux) 有问题。 如果上层的某些应用程序生成接近
我正在使用 ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) 更改接口(interface)的 MTU。 代码类似这样 struct ifreq ifr; ifr.ifr_add
当我通过 TCP 套接字连接时,我的设备出现问题,因为客户端在 SYN 连接中发送 MSS,并且服务器(我的设备)使用相同的 MSS 设置,但我不想在我的设备中设置此 MSS。 那么我怎样才能在MSS
class A : boost::noncopyable { int type; A(int type, enum e) : type(type) { /* ... */ } } ty
我正在学习内核模块并且是新手。我想更改 eth0 的 MTU 大小。这是我写的模块程序。 本意是将 eth0 的 MTU 大小更改为 1000。但它没有得到更改。谁能告诉我,我错过了什么。如果方法本身
我是一名优秀的程序员,十分优秀!