代码之家  ›  专栏  ›  技术社区  ›  Gearoid Murphy

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

  •  10
  • Gearoid Murphy  · 技术社区  · 14 年前

    上下文:我将一个linux perl应用程序移植到C#,服务器监听一个udp端口,并通过一个udp套接字与远程客户端保持多个并发对话。在测试过程中,我向udp服务器发送大量的数据包,随机重启客户端,观察服务器注册新连接的情况。问题是:当我杀死一个udp客户机时,服务器上可能仍然有指向该客户机的数据。当服务器尝试发送此数据时,它会收到一条icmp“无可用服务”消息,因此套接字上会发生异常。

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

    任何帮助或指点将不胜感激。谢谢。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Toad    14 年前

    我认为你说的是对的:“服务器不应该知道”。如果您发送一个UDP数据包到某个IP/端口,它可能是开放的,也可能不是开放的,那么服务器无法知道它是否到达了目的地。

    服务器知道的唯一方法是让客户端发回ACK。(此外,客户端和服务器都必须有适当的重发机制,以防丢失包)。

    因此,很明显,代码(或.NETUDP实现)中发生了其他事情

    尼古拉说了这句话后,我查了一下文件。事实上,在.Net中,使用UDP时“连接”或“无连接”是有区别的。

    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);