我有一个非常简单的异步UDP侦听器,设置为服务,它现在已经运行了一段时间,但它最近在SocketException An existing connection was forcibly closed by the remote host
上崩溃了。我有三个问题:
我的代码如下所示:
private Socket udpSock;
private byte[] buffer;
public void Starter(){
//Setup the socket and message buffer
udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
udpSock.Bind(new IPEndPoint(IPAddress.Any, 12345));
buffer = new byte[1024];
//Start listening for a new message.
EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);
}
private void DoReceiveFrom(IAsyncResult iar){
try{
//Get the received message.
Socket recvSock = (Socket)iar.AsyncState;
EndPoint clientEP = new IPEndPoint(IPAddress.Any, 0);
int msgLen = recvSock.EndReceiveFrom(iar, ref clientEP);
byte[] localMsg = new byte[msgLen];
Array.Copy(buffer, localMsg, msgLen);
//Start listening for a new message.
EndPoint newClientEP = new IPEndPoint(IPAddress.Any, 0);
udpSock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref newClientEP, DoReceiveFrom, udpSock);
//Handle the received message
Console.WriteLine("Recieved {0} bytes from {1}:{2}",
msgLen,
((IPEndPoint)clientEP).Address,
((IPEndPoint)clientEP).Port);
//Do other, more interesting, things with the received message.
} catch (ObjectDisposedException){
//expected termination exception on a closed socket.
// ...I'm open to suggestions on a better way of doing this.
}
}
在recvSock.EndReceiveFrom()行抛出异常。
答案 0 :(得分:15)
从this forum thread开始,UDP套接字似乎也在接收ICMP消息并抛出异常。也许这对于低级状态更新很有用,但我发现它很烦人。
首先,定义幻数
public const int SIO_UDP_CONNRESET = -1744830452;
然后设置低级别io控件以忽略这些消息:
var client = new UdpClient(endpoint);
client.Client.IOControl(
(IOControlCode)SIO_UDP_CONNRESET,
new byte[] { 0, 0, 0, 0 },
null
);
答案 1 :(得分:2)
如果数据包以某种方式被截断或未完全传递,我已经看到了UDP的错误。至少,我想这就是发生的事情。我从来没有能够可靠地复制它。
我建议您抓住SocketException
,记录它(如果需要),然后处置该套接字。然后再次致电Starter
:
catch (SocketException)
{
// log error
udpSock.Close();
Starter();
}