IOCP中10054错误

最近在测试IOCP模型的UDP通讯中发现,如果服务端UDP套接字直接给某个客户端发送数据,而该客户端不存在,会导致  
  上面的GetQueuedCompletionStatus会被激活,但返回错误,数据大小为0,  
  而且再投递WSARecvFrom请求,即使没有客户端发送数据,也会立即收到GetQueuedCompletionStatus  
  返回的错误消息,最终导致再也无法接收客户端数据,经过分析,可以用下面的方式解决该类问题。

 

若要解决此问题,获得最新的 service pack,对于 Windows 2000。有关详细的信息请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:

260910  (http://support.microsoft.com/kb/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 被重写。

详情请见:http://support.microsoft.com/kb/263823
使用方式只需在 UDP SOCKET 创建中调用下述方法即可解决
status = WSAIoctl(sd, SIO_UDP_CONNRESET,
&bNewBehavior, sizeof(bNewBehavior),
                   NULL, 0, &dwBytesReturned,
                   NULL, NULL);

你可能感兴趣的:(windows,socket,Microsoft,service,null,Sockets)