C# · 12月 27, 2021

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

我正在研究一个服务器应用程序(C#,.NET 4.0),它需要每秒处理数千个UDP数据包.所以我决定使用SocketAsyncEventArg来实现服务器.

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

using System;using System.Net;using System.Net.sockets;static class Program{ static void Main(string[] args) { UdpEchoServer.Start(); while (true) { Console.ReadLine(); SendPacket(); } } static void SendPacket() { Console.WriteLine(“SendPacket”); var c = new UdpClient(); c.Send(new byte[5],5,new IPEndPoint(IPAddress.Parse(“127.0.0.1”),445)); c.Close(); }}static class UdpEchoServer{ static Socket mSocket; static byte[] mBuffer; static socketasynceventargs mRxArgs,mTxArgs; static IPEndPoint mAnyEndPoint,mLocalEndPoint; public static void Start() { mAnyEndPoint = new IPEndPoint(IPAddress.Any,0); mLocalEndPoint = new IPEndPoint(IPAddress.Any,445); mBuffer = new byte[1024]; mRxArgs = new socketasynceventargs(); mTxArgs = new socketasynceventargs(); mRxArgs.Completed += ReceiveComplete; mTxArgs.Completed += SendComplete; mSocket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp); mSocket.Bind(mLocalEndPoint); ReceiveNext(); } static void ReceiveNext() { Console.WriteLine(“ReceiveNext”); mRxArgs.RemoteEndPoint = mAnyEndPoint; mRxArgs.SetBuffer(mBuffer,mBuffer.Length); if (!mSocket.ReceiveFromAsync(mRxArgs)) Console.WriteLine(“Error in ReceiveNext: ” + mRxArgs.socketError); } static void ReceiveComplete(object sender,socketasynceventargs e) { Console.WriteLine(“Receive Complete: ” + mRxArgs.socketError); if (mRxArgs.socketError != SocketError.Success) return; mTxArgs.SetBuffer(mBuffer,mRxArgs.BytesTransferred); mTxArgs.RemoteEndPoint = mRxArgs.RemoteEndPoint; Console.WriteLine(“Sending reply packet”); if (!mSocket.SendToAsync(mTxArgs)) Console.WriteLine(“Error in ReceiveComplete: ” + mRxArgs.socketError); } static void SendComplete(object sender,socketasynceventargs e) { Console.WriteLine(“Send Complete: ” + mTxArgs.socketError); if (mTxArgs.socketError != SocketError.Success) return; ReceiveNext(); }}

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

ReceiveNextSendPacketReceive Complete: SuccessSending reply packetSend Complete: SuccessReceiveNextError in ReceiveNext: ConnectionReset

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

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