作者:Ctrliman 链接:https://www.cnblogs.com/henusfs/archive/2009/06/18/UDP.html

作者:任家 链接:http://blog.sina.com.cn/s/blog_4fcd1ea301014z5l.html

解决方案1

用2个UDP连接,一个用来收,一个用来发

解决方案2

  1. UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Loopback, 0));
  2. /*
  3. 解决发送时导致接收出现异常:远程主机强迫关闭了一个现有的连接
  4. 参考:https://www.cnblogs.com/henusfs/archive/2009/06/18/UDP.html
  5. */
  6. uint IOC_IN = 0x80000000;
  7. uint IOC_VENDOR = 0x18000000;
  8. uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
  9. client.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, new byte[4]);

症状

使用UdpClient异步接收时,出现了”远程主机强迫关闭了一个现有的连接”的错误.

重现条件

  1. 使用UdpClient异步接收
  2. 发送时对方没有接收
  3. UDP收和发为同一个

重现代码

  1. static void Main(string[] args)
  2. {
  3. UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Loopback, 0));
  4. client.BeginReceive(ReceiveData, client);
  5. Console.ReadKey();
  6. byte[] bytes = Encoding.UTF8.GetBytes("对称加密:是采用单钥密码系统的加密方法,使用同一密钥对信息进行加密和解密的加密方法。");
  7. client.Send(bytes, bytes.Length, new IPEndPoint(IPAddress.Loopback, 29129));
  8. Console.ReadKey();
  9. }
  10. public static void ReceiveData(IAsyncResult ar)
  11. {
  12. IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 29129);
  13. UdpClient udpClient = ar.AsyncState as UdpClient;
  14. byte[] bs = udpClient.EndReceive(ar, ref endPoint);
  15. Console.WriteLine(Encoding.UTF8.GetString(bs));
  16. udpClient.BeginReceive(ReceiveData, udpClient);
  17. }

当运行到 client.Send 发送方法时,接收就出现了”远程主机强迫关闭了一个现有的连接”的错误

方案1修复后代码

  1. static void Main(string[] args)
  2. {
  3. UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Loopback, 0));
  4. client.BeginReceive(ReceiveData, client);
  5. Console.ReadKey();
  6. UdpClient udpclient = new UdpClient(new IPEndPoint(IPAddress.Loopback, 0));
  7. byte[] bytes = Encoding.UTF8.GetBytes("对称加密:是采用单钥密码系统的加密方法,使用同一密钥对信息进行加密和解密的加密方法。");
  8. udpclient.Send(bytes, bytes.Length, new IPEndPoint(IPAddress.Loopback, 29129));
  9. Console.ReadKey();
  10. }
  11. public static void ReceiveData(IAsyncResult ar)
  12. {
  13. IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 29129);
  14. UdpClient udpClient = ar.AsyncState as UdpClient;
  15. byte[] bs = udpClient.EndReceive(ar, ref endPoint);
  16. Console.WriteLine(Encoding.UTF8.GetString(bs));
  17. udpClient.BeginReceive(ReceiveData, udpClient);
  18. }

方案2修复后代码

  1. static void Main(string[] args)
  2. {
  3. UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Loopback, 0));
  4. uint IOC_IN = 0x80000000;
  5. uint IOC_VENDOR = 0x18000000;
  6. uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
  7. client.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, new byte[4]);
  8. client.BeginReceive(ReceiveData, client);
  9. Console.ReadKey();
  10. byte[] bytes = Encoding.UTF8.GetBytes("对称加密:是采用单钥密码系统的加密方法,使用同一密钥对信息进行加密和解密的加密方法。");
  11. client.Send(bytes, bytes.Length, new IPEndPoint(IPAddress.Loopback, 29129));
  12. Console.ReadKey();
  13. }
  14. public static void ReceiveData(IAsyncResult ar)
  15. {
  16. IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 29129);
  17. UdpClient udpClient = ar.AsyncState as UdpClient;
  18. byte[] bs = udpClient.EndReceive(ar, ref endPoint);
  19. Console.WriteLine(Encoding.UTF8.GetString(bs));
  20. udpClient.BeginReceive(ReceiveData, udpClient);
  21. }