我正在研究一个服务器应用程序(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();
- }
- }
很抱歉长代码,但它非常简单.我等待一个数据包,回复远程终点,然后等待下一个.这是输出:
- ReceiveNext
- SendPacket
- Receive Complete: Success
- Sending reply packet
- Send Complete: Success
- ReceiveNext
- Error 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);