Winsock函数的执行时间太长

时间:2013-03-08 15:39:05

标签: c++ windows winsock

我有一个在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不需要这么长时间才能获取下一个数据包。 但是我找不到关于实际执行时间应该是什么的任何信息。我非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

  1. 提高服务器进程的优先级

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

  2. 增加接收缓冲区大小

    你需要在两端做到这一点。您可以将 setsockopt SO_RCVBUF 选项一起使用:

    int size = 1 * 1024 * 1024;
    setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (const char*)&size, sizeof(int));