可扩展的UDP服务器

3
我需要创建一个服务器,以便监听和响应UDP数据包,它将监听10个端口。这些数据包非常小,不超过20字节。每个数据包都会修改或搜索巨大的哈希表。但是,它必须每秒处理15k个数据包。我可以使用c、c++或qt进行开发。有没有特殊的指导方针来满足这些要求?使用什么基本设计?需要使用线程吗?

1
每分钟15k字相当于每秒250字。这个工作量对于现代桌面/服务器平台来说几乎是微不足道的,所以不用担心。 - Oliver Charlesworth
1
好的,那听起来不太琐碎! - Oliver Charlesworth
你的目标平台是哪些? - Len Holgate
@Len:从提到C++/QT,我就猜是Linux系统。如果是Windows系统,我还可以给出额外的建议。 - Steven Sudit
QT是一个图形用户界面库。你确定这就是你想说的吗? - MarkR
显示剩余7条评论
2个回答

5
对于这种性能,我会考虑采用基于select()的“交换机循环”:
  • 打开监听UDP套接字
  • 调用select()来确定具有可读数据的套接字
  • 对于每个可读套接字,读取字节(非阻塞读取)
  • 当您获得完整的数据包时,进行处理(并根据需要编写)
您可以构建一个简单的表格,以便select()结果进行调度。
这种方法将为您提供最佳性能,因为它与操作系统调用尽可能接近,开销最小。它作为单个进程运行,最小化上下文切换,并获得最佳缓存局部性。
其次,如果您发现受到CPU限制,请考虑使用多个CPU核心和多个线程或进程。例如,您是否可以让每个处理器处理10个套接字中的N个,哈希表在共享内存中。
最后,我会谨慎使用大量线程(例如,大型工作池线程等)。在极高的性能水平下,线程开销可能会变得显着。

好建议。从待处理数据包队列中获取数据的线程池可能是一个不错的选择。 - Steven Sudit
1
实际上,poll() 和特定于平台的系统调用,如 epoll() 和 kqueue 比 select() 更高效。 - ldx
@ldx:不一定——这取决于情况。在许多系统中,poll()和select()非常相似(有时一个被实现为另一个的薄层)。当您有大量文件描述符时,epoll()和kqueue会表现出色。在这里,他只有10个非常高的数据包速率:它们大部分时间都是可读的。 - payne
1
UDP服务器通常不需要使用poll / epoll等可伸缩性工具,因为它只需要一个套接字。原则上,可以使用阻塞读取来实现。 - MarkR

4

Boost.Asio 是可扩展的 UDP 服务器的完美选择。与直接编程到 socket APIs 相比,使用它具有几个优点:

  1. 该库经过成熟验证,自己实现 selectpollepoll 反应器很可能会遇到错误。
  2. 使用 int 表示所有套接字类型缺乏类型安全性,asio 使用诸如 boost::asio::ip::tcp::socketboost::asio::ip::udp::socket 等类型。
  3. 通过提倡异步设计模式而不是每个连接线程来实现,它可以扩展到 数千个并发连接
  4. 添加 多线程支持 以增强可伸缩性非常简单。

Boost.Asio相比直接API调用有哪些优势? - bratao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接