c# – UDP服务器接收数据包的连接重置

前端之家收集整理的这篇文章主要介绍了c# – UDP服务器接收数据包的连接重置前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在研究一个服务器应用程序(C#,.NET 4.0),它需要每秒处理数千个UDP数据包.所以我决定使用SocketAsyncEventArg来实现服务器.

我面临的问题是我的实现只收到一个数据包然后我得到“ConnectionReset”错误(我从未想过我会得到这个错误,因为UDP是无连接的).这是我的测试实现:

  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4.  
  5. static class Program
  6. {
  7. static void Main(string[] args)
  8. {
  9. UdpEchoServer.Start();
  10.  
  11. while (true)
  12. {
  13. Console.ReadLine();
  14. SendPacket();
  15. }
  16. }
  17.  
  18. static void SendPacket()
  19. {
  20. Console.WriteLine("SendPacket");
  21. var c = new UdpClient();
  22. c.Send(new byte[5],5,new IPEndPoint(IPAddress.Parse("127.0.0.1"),445));
  23. c.Close();
  24. }
  25. }
  26.  
  27. static class UdpEchoServer
  28. {
  29. static Socket mSocket;
  30. static byte[] mBuffer;
  31. static SocketAsyncEventArgs mRxArgs,mTxArgs;
  32. static IPEndPoint mAnyEndPoint,mLocalEndPoint;
  33.  
  34. public static void Start()
  35. {
  36. mAnyEndPoint = new IPEndPoint(IPAddress.Any,0);
  37. mLocalEndPoint = new IPEndPoint(IPAddress.Any,445);
  38.  
  39. mBuffer = new byte[1024];
  40.  
  41. mRxArgs = new SocketAsyncEventArgs();
  42. mTxArgs = new SocketAsyncEventArgs();
  43.  
  44. mRxArgs.Completed += ReceiveComplete;
  45. mTxArgs.Completed += SendComplete;
  46.  
  47. mSocket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
  48. mSocket.Bind(mLocalEndPoint);
  49. ReceiveNext();
  50. }
  51.  
  52. static void ReceiveNext()
  53. {
  54. Console.WriteLine("ReceiveNext");
  55.  
  56. mRxArgs.RemoteEndPoint = mAnyEndPoint;
  57. mRxArgs.SetBuffer(mBuffer,mBuffer.Length);
  58.  
  59. if (!mSocket.ReceiveFromAsync(mRxArgs))
  60. Console.WriteLine("Error in ReceiveNext: " + mRxArgs.SocketError);
  61. }
  62.  
  63. static void ReceiveComplete(object sender,SocketAsyncEventArgs e)
  64. {
  65. Console.WriteLine("Receive Complete: " + mRxArgs.SocketError);
  66.  
  67. if (mRxArgs.SocketError != SocketError.Success)
  68. return;
  69.  
  70. mTxArgs.SetBuffer(mBuffer,mRxArgs.BytesTransferred);
  71. mTxArgs.RemoteEndPoint = mRxArgs.RemoteEndPoint;
  72.  
  73. Console.WriteLine("Sending reply packet");
  74.  
  75. if (!mSocket.SendToAsync(mTxArgs))
  76. Console.WriteLine("Error in ReceiveComplete: " + mRxArgs.SocketError);
  77. }
  78.  
  79. static void SendComplete(object sender,SocketAsyncEventArgs e)
  80. {
  81. Console.WriteLine("Send Complete: " + mTxArgs.SocketError);
  82.  
  83. if (mTxArgs.SocketError != SocketError.Success)
  84. return;
  85.  
  86. ReceiveNext();
  87. }
  88. }

很抱歉长代码,但它非常简单.我等待一个数据包,回复远程终点,然后等待下一个.这是输出

  1. ReceiveNext
  2.  
  3. SendPacket
  4. Receive Complete: Success
  5. Sending reply packet
  6. Send Complete: Success
  7. ReceiveNext
  8. Error in ReceiveNext: ConnectionReset

请问您能否在上面的代码片段中提出错误建议?

解决方法

使用UDP套接字会发生这种情况.您需要做的就是在绑定之前更改 socket operating mode.在Start方法中使用此代码.
  1. mSocket = new Socket(AddressFamily.InterNetwork,ProtocolType.Udp);
  2.  
  3. const int SIO_UDP_CONNRESET = -1744830452;
  4. byte[] inValue = new byte[] {0};
  5. byte[] outValue = new byte[] {0};
  6. mSocket.IOControl(SIO_UDP_CONNRESET,inValue,outValue);
  7.  
  8. mSocket.Bind(mLocalEndPoint);

猜你在找的C#相关文章