使用 C/C++ 套接字模拟网络状况

Simulate network conditions with a C/C++ Socket

本文关键字:模拟网 网络状 模拟 套接字 C++ 使用      更新时间:2023-10-16

我正在寻找一种将网络仿真添加到套接字的方法。

基本解决方案是某种向连接添加带宽限制的方法。

对我来说,理想的解决方案是:

  • 支持高级网络属性(延迟、数据包丢失)
  • 开源
  • 具有与标准套接字类似的 API(或环绕它们)
  • 在 Windows 和 Linux 上工作
  • 支持 IPv4 和 IPv6

看到了一些在系统级别工作的选项,甚至可以作为代理(Dummynet,WANem,neten等),但这对我不起作用,因为我希望能够手动模拟每个套接字(例如,打开一个带有调制解调器仿真的套接字和一个带有3G仿真的套接字。基本上我想知道这些工具是如何做到的。

编辑:我需要在我自己的产品中嵌入此功能,因此使用额外的盒子或需要手动配置的第三方工具是不可接受的。我想编写与这些工具做同样事情的代码,我的问题是如何做到这一点。

尾声:事后看来,我的问题有点误导。显然,没有办法直接在插座上做我想做的事情。有两种选择:

添加发送/接收操作的延迟(基于 @PaulCoccoli 的回答):
通过在发送和接收之前添加延迟,您可以获得非常粗略的网络模拟(延迟恒定延迟,延迟发送,每秒发送不超过 X 字节,带宽)。
保罗的回答和评论给了我很大的启发,所以我给了他赏金。

添加网络模拟逻辑作为代理(基于 @m0she 和其他答案):
通过代理发送请求,或使用代理拦截请求,然后添加所需的模拟。但是,使用现成的解决方案而不是编写自己的代理实现更有意义 - 据我所知,Dummynet 可能是最佳选择(这就是 webpagetest.org 所做的)。其他选项在下面的答案中,我还将添加DonsProxy
这是更好的方法,所以我接受这个答案。

您可以将代理编译到您的软件中,以执行此操作。它可以是成熟的袜子代理的一些实现(像这样),或者可能更好,更简单的东西,只服务于您的目的(并且不需要前缀您与目的地和其他袜子开销的通信)。该代码可以作为单独的进程或进程中的线程运行。

向代理添加限制应该不会太难。您可以:

  • 如果数据超过某些带宽限制,则延迟数据转发
  • 通过在缓冲区的读/写操作之前添加计时器来增加延迟。
  • 如果您使用的是基于连接的协议(如TCP),则丢弃数据包是没有意义的,但是使用基于数据报的协议(UDP)也很容易实现。

连接创建 API 与普通的 posix/winsock 有点不同(除非您执行一些宏或其他魔法),但其他所有内容(发送/recv/select/close/等)都是一样的。

如果要将其构建到产品中,则应在套接字API上实现一个抽象层,以便在运行时选择自己的实现。 或者,您可以实现每个套接字函数的包装器,并选择是调用您自己的版本还是系统的版本。

至于增加延迟,你可以让你的套接字API实现脱离一个线程。 在该线程中,有一个按时间排序的优先级队列(即,此后台线程执行非常基本的离散事件模拟)。 您发送或接收的每个"数据包"都可以与交货时间一起排队。 每个交货时间都应该增加一些延迟。 我会使用某种具有高斯分布的随机数生成器。

后台线程还必须模拟连接的另一端,尽管听起来您可能已经实现了该部分?

我只知道 Mac OS X Lion 的 Network Link Conditioner。您应该是Mac开发人员才能下载它,所以我无法将下载链接放在那里。只有来自 9to5mac.com 的描述:http://9to5mac.com/2011/08/10/new-in-os-x-lion-network-link-conditioner-utility-lets-you-simulate-internet-and-bandwidth-conditions/

这个答案可能是使用 Linux 时的部分解决方案:在 Linux 上模拟延迟和丢弃的数据包。它指的是一个名为netem的内核模块,可以模拟各种网络问题。

如果要使用 TCP 连接,"数据包丢失"可能会有问题,因为许多错误处理(如恢复丢失的包)都是在内核中完成的。以跨平台的方式模拟这一点可能很困难。

通常会向网络添加一个网络设备,以限制带宽或延迟,然后只需连接到分配给要测试的特定类型的蹩脚网络的端口即可实现所需的目标,而无需更改或修改代码。

最简单的方法是将iptables规则添加到充当代理的Linux服务器中。

如果您希望它在没有单独设备的情况下工作,请尝试涓流,这是一个软件包,可限制客户端 PC 上的网络。(或适用于视窗)

您可能

想检查WANem http://wanem.sourceforge.net/。WANEM 是开源的,并在 GNU 通用公共许可证下获得许可。

WANem 允许应用程序开发团队设置一个透明的应用程序网关,该网关可用于模拟 WAN 特征,如网络延迟、数据包丢失、数据包损坏、断开连接、数据包重新排序、抖动等。

我认为您可以使用像Network Simulator这样的工具。它是免费的,适用于Windows。

唯一要做的就是将程序设置为使用正确的端口(当然还有网络的设置)。

如果您想要一个您控制的纯软件解决方案,则必须自己实现它。据我所知,没有这样的现有一揽子计划。

虽然套接字上的包装层可能使您能够引入延迟,但不足以引入丢失或无序交付。为了模拟这些活动,您实际上需要拦截两个 TCP 堆栈之间传输的数据。

我推荐的方法是使用隧道设备(比如tunX)。应设置路由,以便客户端认为到服务器的方式是通过tunX。额外的代码(可能在不同的线程中运行)会混杂地拦截tunX上的流量,并执行您的增强行为,然后通过真正的物理接口转发数据包,将流量发送到您的服务器。对于从物理接口上的服务器到达的数据包,情况正好相反。这些数据包将被客户端代码拦截,行为增强,然后通过tunX转发。

但是,由于您正在测试客户端软件,我不清楚为什么要将此代码嵌入到已发布的软件中,除非该软件本身是 WAN 模拟客户端。

相关文章:
  • 没有找到相关文章