C# 异步 UDP 侦听器 SocketException
我有一个非常简单的异步 UDP 侦听器,设置为服务,并且它已经工作了一段时间,但它最近因 SocketException 现有连接被远程主机强制关闭
而崩溃。我有三个问题:
- 这是什么原因造成的? (我不认为 UDP 套接字有连接)
- 出于测试目的,我如何复制它?
- 我怎样才能干净地处理异常,以便一切都能继续工作?
我的代码如下所示:
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() 行引发异常。
I have a pretty simple Asynchronous UDP listener, setup as a service, and it's been working quite well for awhile now, but it recently crashed on a SocketException An existing connection was forcibly closed by the remote host
. I have three questions:
- What's causing this? (I didn't think UDP sockets had a connection)
- How can I duplicate it, for testing purposes?
- How can I cleanly handle the exception, so everything will continue to work?
My code looks something like the following:
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.
}
}
The exception is being thrown at the recvSock.EndReceiveFrom() line.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
来自此论坛帖子,看来UDP套接字也在接收ICMP消息并在接收时抛出异常。也许这对于低级别状态更新很有用,但我发现它很烦人。
首先,定义幻数
然后设置低级 io 控制以忽略这些消息:
From this forum thread, it seems that the UDP socket is also receiving ICMP messages and throwing exceptions when they are received. Maybe this is great for low level status updates, but I found it annoying.
First, define the magic number
Then set the low level io control to ignore these messages:
如果数据包以某种方式被截断或未完全传送,我已经看到 UDP 的错误。至少,我认为就是这样。我从来没能可靠地复制它。
我建议您捕获 SocketException,记录它(如果您愿意),然后处理该套接字。然后再次调用
Starter
:I've seen that error with UDP if a packet is somehow truncated or otherwise not completely delivered. At least, I think that's what happens. I've never been able to duplicate it reliably.
I would suggest that you catch the
SocketException
, log it (if you want), and then dispose of that socket. Then callStarter
again: