如何从C#udp套接字异常中优雅地恢复

时间:2010-04-10 12:25:46

标签: c# sockets udp

上下文:我正在将一个Linux perl应用程序移植到C#,服务器侦听一个udp端口,并通过一个udp套接字维护与远程客户端的多个并发对话框。在测试期间,我向udp服务器发送大量数据包,随机重启客户端以观察服务器注册新连接。问题是这样的:当我杀死一个udp客户端时,服务器上可能仍然存在发往该客户端的数据。当服务器尝试发送此数据时,它会返回icmp“无服务可用”消息,因此套接字上发生异常。

我无法重用此套接字,当我尝试将C#异步处理程序与套接字关联时,它会抱怨异常,所以我必须关闭并重新打开服务器端口上的udp套接字。这是解决这个问题的唯一方法吗?肯定有一些“修复”udp套接字的方法,从技术上讲,UDP套接字不应该知道远程套接字的状态?

非常感谢任何帮助或指示。感谢。

1 个答案:

答案 0 :(得分:1)

我认为你说得对:'服务器不应该知道'。如果您将UDP数据包发送到可能打开或未打开的某个IP /端口,则无法知道服务器是否到达目的地。

服务器知道的唯一方法是让客户端发回ACK。 (在丢失包的情况下,客户端和服务器都必须具有重新发送机制)。

很明显,你的代码(或使用.Net udp实现)还会发生其他事情

编辑:

在尼古拉的评论之后,我检查了文档。事实上,在使用UDP时,.Net与“连接”或“无连接”有区别。

如果你使用这样的代码:

UdpClient udpClient = new UdpClient(11000); //sourceport
try{
     udpClient.Connect("www.contoso.com", 11000); //'connect' to destmachine and port
     // Sends a message to the host to which you have connected.
     Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody there?");
     udpClient.Send(sendBytes, sendBytes.Length);

然后显然你是'连接'

但是,如果你使用这样的代码:

     UdpClient udpClientB = new UdpClient();
     udpClientB.Send(sendBytes, sendBytes.Length, "AlternateHostMachineName", 11000);

然后您可以在没有“连接”的情况下发送给您选择的任何人。

我不确定你的代码是什么样的,但是检查你是否正在使用不假设'连接'的正确命令集可能是值得的