更快的WinSock sendto()

时间:2011-09-04 16:23:44

标签: c++ winsock sendto

我正在使用Windows Server 2008,我的程序是用C ++编写的。 我在一个while(true)循环中使用WinSock2和sendto()来发送我的数据包。

代码如此:

while(true)
{
    if(c == snd->max)
        c = snd->min;

    dest.sin_addr.S_un.S_addr = hosts[c];
    iphead->destaddr = hosts[c];

    sendto(s, castpacket, pktsz, 0, castdest, szsad);

    ++c;
}

我需要尽可能快地向我的主机std :: vector中的尽可能多的IP发送数据。

我目前正在运行i7 930服务器,而我只能达到350Mbps左右。

我目前将我的程序拆分为4个线程,所有线程都运行while循环,并为每个线程分配不同的服务器。 添加更多线程或运行更多程序副本会导致吞吐量降低。

我有另一个程序正在运行侦听来自服务器的回复。我从主列表中获取服务器并将它们添加到我的阵列中。目前的问题是,通过所有这些问题需要很长时间,我想定期检查它们。

我如何才能在此优化程序/循环/发送?

3 个答案:

答案 0 :(得分:2)

我建议转到异步I / O以加快速度。一次发送一个的主要问题是,当TCP堆栈处理当前数据包时,您无法排队下一个数据包。

另外,您可以采用线程池方法:触发一定数量的工作线程,每个线程从FIFO中获取客户端并将数据发送到客户端。当线程完成其客户端时,它将客户端放回FIFO中并获取一个新客户端。你可以通过调整工作线程的数量来填充管道 - 但不要淹没它。

答案 1 :(得分:1)

看看WinSock的Registered I/O Extensions(RIO)API:

RIO API是Windows套接字(Winsock)的新扩展,它为您提供了机会来减少网络延迟,提高消息速率并提高对要求非常高的应用程序的响应时间的可预测性性能,非常高的消息率和可预测性。 RIO API扩展允许处理大量小消息的应用程序实现更高的每秒I / O操作(IOPS),同时减少抖动和延迟。 具有高消息速率和低延迟要求的服务器负载受益于RIO API扩展,其中包括金融服务交易和高速市场数据接收和发布的应用程序。此外,当您在一台物理计算机上部署许多Hyper-V虚拟机(VM)时,RIO API扩展可提供较高的IOPS。

RIO允许使用请求和完成队列使用预先注册的缓冲区执行发送和接收操作。发送和接收操作排队到与Winsock套接字关联的请求队列中。已完成的I / O操作被插入到完成队列中,并且许多不同的套接字可以与同一完成队列关联。完成队列也可以在发送和接收完成之间分配。诸如轮询之类的完成操作可以完全在用户模式下执行,而无需进行系统调用。

使用已注册的缓冲区可简化与网络相关的处理,减少抖动,并使应用程序开发人员可以指定协议栈使用的网络缓冲区的NUMA节点亲和力-进一步提高整体性能,并减少延迟和抖动特征。

RIO API扩展支持传输控制协议(TCP),用户数据报协议(UDP)多播UDP ,以及IPv4和IPv6。

如果要实现以下任何一项,则可以使用RIO API扩展:

  • 扩展服务器以最大程度地减少每条消息的CPU利用率

  • 将网络堆栈的延迟贡献和抖动降至最低

  • 处理非常高的多播或UDP流量

使用RIO API扩展还具有以下其他优点:

  • RIO可在Windows Server 2012的所有版本上使用。

  • RIO与普通的网络适配器兼容,不需要特殊的网络适配器或RDMA。

  • RIO与现有Windows网络功能完全兼容,包括RSS,RSC,网络接口卡分组和静态卸载。

  • 在Windows Server 2012中部署Hyper-V时,RIO可与虚拟化一起使用。

  • RIO套接字使用标准的Windows网络堆栈以及标准的TCP / IP和UDP协议。

答案 2 :(得分:0)