0

我有一个在 Windows XP 平台(i7 2.1 Ghz 处理器)上运行的应用程序。此应用程序是主节点和从节点之间通过 UDP 进行的基于主/从的通信。主节点发送请求,从节点发送响应(突发模式),每 5 ms 发送一个数据包,每个数据包长 1300 字节,包括标头。

回到主节点,主线程接收数据并将其写入队列,触发并行线程从线程中读取。

问题:Winsock API 在读取下一个数据包时执行时间很长,因此缓冲区中的数据正在丢失。

执行时间:Recvfrom() - 200 - 400 微秒。

Open_Sock ()
{
    socket();
    //Error check

    connect ();
    //Error Check
}

Receivethread()
{
    sock again:

    select(socket, read,write,excep,(0,0));
    //error check

    rc = recvfrom(socket,buf,len,0,&s_addr,&cln_alen)
    if(rc>0) {
        enqueue(queue,buf);
    }
}

我确信 Winsock API 不需要这么长时间来获取下一个数据包。但我找不到任何关于实际执行时间的信息。在这个方向上的任何帮助都非常感谢。

4

2 回答 2

0

如果丢失数据包是一个问题,请使用 TCP。使用 TCP,我在不太现代的机器上实现了不到一毫秒的响应时间,用于简单的环回连接。那里有一些重要的点:

  • 等待流量时将 WSAEventSelect() 与 WaitForMultipleObjects() 结合使用。我不确定这与 select() 相比是否有很大的不同,但如果你想用一个额外的事件来停止线程,它会使处理更容易。
  • 在等待输入之前分配一个缓冲区,这仍然可以减少延迟。
  • 尽量不要为每个数据包创建一个线程,而是让线程已经在等待,即使用线程池。
  • 尝试发送尽可能少的数据包,即尝试将整个数据组装到内存中并通过一次调用发送。这避免了稍后组装的多个数据包的网络 IO 开销。
  • 另请查看 Nagle 算法,您可能希望为 TCP 关闭该算法。Nagle 算法与延迟确认相结合会严重影响您的延迟。
于 2013-03-09T08:14:32.687 回答
0

您可能遇到了发送/接收缓冲区大小和操作系统调度程序问题的组合。在 Windows 平台上,线程之间的上下文切换不是太频繁,因此您可以使用两个选项:

  1. 增加服务器进程的优先级

    这将减少您的服务器应用程序停留在队列中的时间。

  2. 增加接收缓冲区大小

    你需要在两端都这样做。您可以将setsockoptSO_RCVBUF选项一起使用:

    int size = 1 * 1024 * 1024;
    setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (const char*)&size, sizeof(int));
    
于 2013-03-13T10:56:19.363 回答