症状
在 Windows 2000 用户数据报协议 (UDP) 的程序可能无法工作,并且可能生成 WSAECONNRESET 响应。
原因
如果为 readfds 设置了一个使用中的"无法到达 ICMP 端口"响应和 选择 函数 sendto 函数结果的数据报发送该程序就会返回 1 和后续调用 recvfrom 函数使用 WSAECONNRESET (10054) 错误响应无法正常工作。在 Microsoft Windows NT 4.0,这种情况下将导致 选择 函数块或超时时间。
解决方案
若要解决此问题,获得最新的 service pack,对于 Windows 2000。有关详细的信息请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
260910 如何获取最新的 Windows 2000 service pack
在 Windows 2000 引入了新的套接字 IOCTL 称为"SIO_UDP_CONNRESET"。专门为获取原始的 Windows NT 4.0 的 Windows 2000 在使用此 IOCTL 时必须重写该程序的行为。Windows NT 4.0、 Microsoft Windows 95,和 Microsoft Windows 98 具有不支持此新 IOCTL。除了重写应用程序,您将需要引用该修补程序在本文中进一步。
下面的代码段演示一种技术,它可用于获取原始的 Windows NT 4.0 行为 SIO_UDP_CONNRESET 控件代码中调用 WSAIoctl
DWORDdwBytesReturned = 0;
BOOLbNewBehavior = FALSE;
DWORDstatus;
// disable new behavior using
// IOCTL: SIO_UDP_CONNRESET
status = WSAIoctl(sd, SIO_UDP_CONNRESET,
&bNewBehavior, sizeof(bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL);
if (SOCKET_ERROR == status)
{
DWORD dwErr = WSAGetLastError();
if (WSAEWOULDBLOCK == dwErr)
{
// nothing to do
return(FALSE);
}
else
{
printf("WSAIoctl(SIO_UDP_CONNRESET) Error: %d/n", dwErr);
return(FALSE);
}
}
要对其进行编译此代码,您需要具有在最新 Mswsock.h,其中包括 SIO_UDP_CONNRESET 的定义,或定义它的直接向代码在下方插入
// MS Transport Provider IOCTL to control
// reporting PORT_UNREACHABLE messages
// on UDP sockets via recv/WSARecv/etc.
// Path TRUE in input buffer to enable (default if supported),
// FALSE to disable.
#defineSIO_UDP_CONNRESET_WSAIOW(IOC_VENDOR,12)
注意 本文中介绍的修补程序不会解决此问题,除非该程序会使用新的 SIO_UDP_CONNRESET IOCTL 被重写。
若要编译此代码,它是需要让您的计算机上安装最新的平台 SDK。这提供了下面的 MSDN 网站:
http://msdn.microsoft.com
状态
Microsoft 已经确认这是在本文开头列出的 Microsoft 产品中的问题。 Windows 2000 Service Pack 2 中,第一次已得到纠正此问题。
有关如何一次安装 Windows 2000 和 Windows 2000 修补程序的详细信息单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
249149 安装 Microsoft Windows 2000 和 Windows 2000 修补程序
这篇文章中的信息适用于:
Microsoft Windows 2000 Server
Microsoft Windows 2000 Advanced Server
Microsoft Windows 2000 Professional Edition