recv()没有时间从Win 7上的套接字接收所有UDP数据包?

时间:2011-11-10 12:37:43

标签: windows sockets udp

我正在为Windows XP和Seven开发网络应用程序。应用程序通过UDP接收数据并使用阻塞套接字,选择(不是WSAPoll)和recv函数。

为了测试,我使用两个安装了不同操作系统的相同笔记本:Dell Latitude D630,Core 2 Duo 2.2GHz,4Gb RAM,Broadcom NetXtreme 57xx千兆控制器。我得到了以下结果:

Windows XP Professional 32位:网络监视器应用程序显示网络接口从LAN接收数据,平均速度为35 MBytes / s。应用程序从平均速度为30 MBytes / s的套接字接收数据,并检测到13%的丢失。

Windows 7 Enterprise 32位:网络监视器应用程序显示网络接口从LAN接收数据,平均速度为35 MBytes / s。应用程序从平均速度为10 MBytes / s的套接字接收数据,并检测到65%的丢失。

看起来应用程序没有足够的时间从Windows 7上的套接字接收所有数据包。但为什么结果与Win XP不同?

1 个答案:

答案 0 :(得分:0)

我正在为处理此类或类似问题的任何人提供以下内容,因为我在处理类似的事情时遇到了这个问题。我希望这能节省一些时间。

我还要感谢@Roman R.上述评论和@ Rom098跟进评论,指出缓冲区大小的变化也有助于他/她。

使用带有低数据速率UDP的Windows套接字在多个终端之间进行数据通信的应用程序在Windows XP中运行良好,但转移到Windows 7后,我们开始遇到网络消息被丢弃的问题。

架构是客户终端通过发送和接收一系列UDP消息与客户端保持其自身状态来与服务器终端进行对话。客户终端具有线程,客户线程,其处理用户输入以及向服务器终端发送和接收消息。服务器终端有一个线程,服务器线程,它处理来自其他终端的请求消息以及它自己的客户端线程。简单的消息序列如下所示:

  • 客户端终端向服务器终端发送请求消息
  • 服务器终端以确认消息响应
  • 服务器终端处理请求并向客户端发送响应消息
  • 客户端终端向服务器终端发送确认

查看上面的评论,我们使用调试器进行了检查,发现Windows 7的默认WinSock接收和发送缓冲区大小为8K(8192字节)。在互联网上看,似乎Windows XP对网络流量的处理率更高。

我们在网络层进行了两项处理通信的更改。

第一种是使用setsockopt()函数使用以下代码将接收和发送缓冲区的大小加倍。

iOptLen = sizeof(INT);
error = getsockopt (iSocket, SOL_SOCKET, SO_RCVBUF, (PCHAR)(&iOpt), &iOptLen);
if (error < 0) {
    error = WSAGetLastError();
} else if (iOpt < 1024 * 16) {
    iOpt = 1024 * 16;
    error = setsockopt(iSocket, SOL_SOCKET, SO_RCVBUF, (const PCHAR)(&iOpt), sizeof(iOpt));
    if (error < 0) {
        error = WSAGetLastError();
    }
}
iOptLen = sizeof(INT);
error = getsockopt (iSocket, SOL_SOCKET, SO_SNDBUF, (PCHAR)(&iOpt), &iOptLen);
if (error < 0) {
    error = WSAGetLastError();
} else if (iOpt < 1024 * 16) {
    iOpt = 1024 * 16;
    error = setsockopt(iSocket, SOL_SOCKET, SO_SNDBUF, (const PCHAR)(&iOpt), sizeof(iOpt));
    if (error < 0) {
        error = WSAGetLastError();
    }
}

我们做的第二个更改是客户端线程正在等待确认,并且响应消息从服务器终端进入,然后将响应消息作为确认和响应的组合进行处理。我们正在做的是假设确认消息在某个时候被删除了。

通过这两项更改,虽然我们的测量表明有时从服务器终端到客户终端的确认消息仍然被丢弃,但滞后不再明显。

另见

Change default socket buffer size under Windows使用Windows注册表更改将默认缓冲区大小从8K修改为其他内容。

然而,有关TCP的

What is the size of a socket send buffer in Windows?提供了有关setsockopt()的其他信息。

Winsock UDP packets being dropped?讨论了类似的问题,提供了许多答案,提供了额外的信息。

来自Innominate.com的

Application Note: Windows 2000/XP TCP Tuning for High Bandwidth Networks有一些有趣的信息,但也许有点过时了,据我所知,在Windows 7中,网络层被重写了。

来自Michael Pan的codeProject.com上的

Real time communications over UDP protocol提供了有关使用UDP的技术问题的相关细节。