情况如下:
    有个echo的UDP服务器,它收到客户端发来的数据后再原封不动地发回给客户端。代码片段大致如下:
while(true)
{
nAddrLen = sizeof(SOCKADDR_STORAGE);
if((nRecvdBytes = recvfrom(ReceivingSocket, szRecvBuf, 256, 0, (sockaddr*)&SenderAddr, &nAddrLen)) == SOCKET_ERROR)
{
cout<<"ERROR: recvfrom failed with error: "<<WSAGetLastError()<<endl;
closesocket(ReceivingSocket);
WSACleanup();
break;
} Ret = sendto(ReceivingSocket, szRecvBuf, nRecvdBytes, 0, (SOCKADDR *)&SenderAddr, nAddrLen);
if(SOCKET_ERROR == Ret)
{
cout<<"ERROR: sendto failed with error: "<<WSAGetLastError()<<endl;
closesocket(ReceivingSocket);
WSACleanup();
break;
}
}
    现在的问题是:当UDP服务器接收到数据之后,在它把数据发送给客户端之前,客户端关闭了,这时发送就会导致一个ICMP端口不可达的错误。当然,那个sendto操作还是会成功的,只是下一次的recvfrom操作就会出错,返回的错误代码是WSAECONNRESET,MSDN上是这样解释的:
On a UDP-datagram socket this error indicates a previous send operation resulted in an ICMP Port Unreachable message.为了不让这个recvfrom操作出错,我是这样解决的:
在创建了这个UDP的服务器端socket之后,就给它的I/O设置了个属性
BOOL bConnReset = FALSE;
DWORD dwBytesReturned = 0;
WSAIoctl(ReceivingSocket, SIO_UDP_CONNRESET, (void*)&bConnReset, sizeof(BOOL), (void*)&Ret, sizeof(int), &dwBytesReturned, 0 ,0);想问问各位,你们是怎么处理Winsock编程中的UDP错误的?

解决方案 »

  1.   

    >>那个sendto操作还是会成功的
    为什么会成功啊?应该也是WSAECONNRESET
      

  2.   

    UDP....
    如果你需要处理错误,可能就不该用UDP最简单就是保留你要发送的数据,以后再重试了
    还能怎么处理
    怎么处理与你要发的东西有关啊
    你无所谓的东西扔掉就不管好了
      

  3.   

    我的意思是:sendto能否成功是无所谓的,但是问题是sendto之后,再掉recvfrom就会出错。也就是说UDP服务器在发生一个sendto错误后就没办法继续接收其他UDP客户端发来的数据了,这当然不是我想要的结果。为了解决这个问题,我在创建socket后调用了WSAIoctl函数修改了socket的属性。recvfrom就可以继续接收数据。我是想问:有没有人遇到过类似的问题,你们是怎么处理的?To:xujianlane(头文字C)。sendto为什么会成功呢?对于sendto产生的WSAECONNRESET错误,MSDN上是这么说的:For UPD sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet. The application should close the socket as it is no longer usable.
    的确,第一次的send是会成功的(事实上对方其实根本没有收到这个UDP包),但是它已经导致了一个ICMP端口不可达错误的产生,因此接下来在这个socket上调用recvfrom会出错。如果这个时候再调一次sendto,就会得到一个WSAECONNRESET错误了。To:partime(partime)。你似乎没有明白我说的是什么,不过还是谢谢你顶帖。
      

  4.   

    我从来是通过select来处理
    不会有recvfrom发生错误的情况
    在网络底层出错时recvfrom接收0字节
      

  5.   

    OK了,去Google了一把,看到别人也是这么解决的。
    开来以后有什么问题还是应该先Google一下,不要动辄就上论坛啊!