WinSock Recvfrom() now returns WSAECONNRESET instead of blocking or timing out

WinSock Recvfrom() now returns WSAECONNRESET instead of blocking or timing out

This article was previously published under Q263823
This article has been archived. It is offered "as is" and will no longer be updated.
SYMPTOMS
In Windows 2000, a User Datagram Protocol (UDP) program may not work and may generate a WSAECONNRESET response.
CAUSE
If sending a datagram using the sendto function results in an "ICMP port unreachable" response and the select function is set for readfds, the program returns 1 and the subsequent call to the recvfrom function does not work with a WSAECONNRESET (10054) error response. In Microsoft Windows NT 4.0, this situation causes the select function to block or time out.
RESOLUTION
To resolve this problem, obtain the latest service pack for Windows 2000. For more information, click the following article number to view the article in the Microsoft Knowledge Base:
260910 How to obtain the latest Windows 2000 service pack
A new sockets IOCTL called "SIO_UDP_CONNRESET" has been introduced in Windows 2000. When this IOCTL is used, the program must be rewritten specifically for Windows 2000 to obtain the original Windows NT 4.0 behavior. Windows NT 4.0, Microsoft Windows 95, and Microsoft Windows 98 have no support for this new IOCTL. In addition to rewriting your application, you will need the hotfix referenced further down in this article.

The following code snippet demonstrates a technique that can be used to call WSAIoctl with the SIO_UDP_CONNRESET control code to obtain the original Windows NT 4.0 behavior.

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);
}
}
				
To be able to compile this code, you need either to have the latest Mswsock.h which includes the definition of SIO_UDP_CONNRESET or to insert below definition of it directly into your code.

// 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)
				
Note The hotfix that is described in this article will not resolve the problem unless the program is rewritten to use the new SIO_UDP_CONNRESET IOCTL.

In order to compile this code, it is necessary to have the latest Platform SDK installed on your computer. This is available from the following MSDN Web site:
STATUS
Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article. This problem was first corrected in Windows 2000 Service Pack 2.
MORE INFORMATION
For more information about how to install Windows 2000 and Windows 2000 hotfixes at the same time, click the following article number to view the article in the Microsoft Knowledge Base:
249149 Installing Microsoft Windows 2000 and Windows 2000 hotfixes
Properties

Article ID: 263823 - Last Review: 12/05/2015 20:25:12 - Revision: 4.3

  • Microsoft Windows 2000 Server
  • Microsoft Windows 2000 Advanced Server
  • Microsoft Windows 2000 Professional Edition
    • kbnosurvey kbarchive kbhotfixserver kbqfe kbbug kbfix kbwin2000presp2fix KB26382

    from https://support.microsoft.com/en-us/kb/263823#%2Fen-us%2Fkb%2F263823

    PS: 虽然知识库说的windows 2000导致的问题,但是同事在开发过程中发现windows 7也复现了此问题,所以在开发UDP程序时,还是调用
    WSAIoctl(sd, SIO_UDP_CONNRESET,....代码吧。
    • 0
      点赞
    • 1
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值