首页 文章

UDP负载测试:如何模拟许多UDP客户端?

提问于
浏览
3

我正在开发一个工具来在UDP服务器上执行负载测试(使用在NT 6.x上运行的C#/ .NET 4.0,尽管这不太相关) . 服务器与数万个客户端进行通信,每个客户端之间的通信流量非常低且不经常 . 所有通信都遵循请求 - 回复模式,其中一方开始与另一方进行通信,然后另一方回复 . 当服务器需要向客户端发送内容时,他查找客户端的最后一个已知 endpoints (IP端口)并发送UDP数据包,并在单个已知端口上侦听回复,该端口用于接收来自所有客户端的通信 . 当客户端启动通信时,它已经知道服务器的 endpoints ,并且只是从临时端口发送数据包并等待同一端口上的回复 . 在客户端的生命周期中使用相同的临时端口 .

负载测试工具的设计非常简单;模仿每个客户的行为,状态和决策,以低而充足的复杂性 . 由于与每个客户端的通信只是偶然的(每隔几秒),并且每次通信所需的处理量非常小,我能想到的最佳方法是使用单个线程与单个套接字来执行所有通信对于大量模拟客户端,很可能仍然不会使线程完全忙并且套接字饱和 . 不幸的是,由于每个客户端从他自己的端口发送和接收这一事实,我遇到了两个问题:

  • 套接字仅允许从系统分配的临时端口或套接字绑定的特定端口发送UDP数据包 .

  • 套接字只接收来自绑定端口的UDP数据包 .

每个客户端一个套接字

以上两个约束似乎意味着我必须为每个客户端创建一个套接字,因为UDP数据包必须来自某个端口,并且回复将被发送到该端口 . 所以第一个可能的解决方案就是这样做,为每个模拟客户端创建一个套接字 . 假设我们在一台机器上模拟30,000个客户端:

  • 创建30,000个套接字甚至可行吗?这是最佳做法吗?它表现得好吗? Windows甚至可以让你将30,000个套接字绑定到30,000个不同的端口吗?

  • 如果服务器发送了任何数据,如何检查30,000个客户端套接字?我是否定期轮询所有套接字以查看是否收到了任何数据?有没有办法等待所有30,000个套接字并获得第一个到达其中任何一个的数据包?

  • 操作系统为每个套接字分配了哪些资源?每种资源的限制是什么?达到这些资源的意义是什么?

所有客户端的单个套接字

一种不同的方法是使用单个套接字,但我之前提到的两个问题必须首先以某种方式解决:

  • 将UDP数据包发送到Socket端口以外的端口的第一个问题是可解决的 . 它涉及创建一个原始套接字并自己构建UDP header,这意味着您可以指定任何您想要的源和目标端口 . 唯一的困难是计算可选但重要的UDP checksum,它不仅需要UDP头和有效负载,还需要源和目标IP地址,前者是有问题的,因为它需要调用Win32 API来获取(GetBestInterfaceGetAdaptersInfo),这涉及到几个本机结构和大量非托管内存分配,从.NET角度来看可能存在潜在的可靠性缺陷,但它可以完成 .

  • 第二个问题,使用单个套接字从列表(或范围)端口接收UDP数据包仍然没有得到我的解决 . 即使使用原始套接字,操作系统也要求我在允许我执行接收操作之前将套接字绑定到特定的单个端口 . 有没有办法做到这一点?除非可以通过可靠且有点直接的方式从托管代码完成,否则's always the packet sniffing techniques, but I' d宁可避免它们(在这种情况下,我愿意接受建议) .

其他方法?

还有其他方法我没有想过吗?我走错了路吗?你能想到更好的解决方案吗?我很想听听你的任何建议 .

1 回答

  • 4

    是的,您可以在Windows机器上轻松创建> 30,000个套接字,但您可能需要调整 MAXUSERPORT (请参阅here) .

    使用I / O完成端口,或异步I / O然后你不需要担心'轮询'和可扩展性“只是工作” .

    主要资源问题是非页面缓冲池,但这在Vista或更高版本上已经变得不那么严重(请参阅here),下一个问题是I / O锁定页面限制,如果您发布非常大的缓冲区可能会出现问题对于你的读取,但鉴于这是UDP,我认为你合理的'大小的数据报和锁定的页面限制是不可能是一个问题 .

    我在这里写了一些关于可伸缩性问题的博客:http://www.serverframework.com/asynchronousevents/2010/12/one-million-tcp-connections.html

    我've written tools similar to what you'正在尝试使用我的C++ socket server framework . 有一个UDP测试工具示例作为框架的一部分提供,它从唯一的客户端端口发送可配置数量的数据报并等待回复,并且易于调整以处理您的特定数据报格式和响应要求(请参阅here) .

相关问题