I am working on a server application (C#, .NET 4.0) that will need to handle thousands of UDP packets every second. So I decided to SocketAsyncEventArg
to implement the server.
The problem I am facing is that my implementation receives just one packet and then I get "ConnectionReset" error (I never imagined I could get this error because UDP is connection-less). Here is my test implementation:
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, 0, 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, 0, 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();
}
}
Sorry for long code but it is really simple. I wait for a packet, reply to remote end point and then wait for next one. Here is the output:
ReceiveNext
SendPacket
Receive Complete: Success
Sending reply packet
Send Complete: Success
ReceiveNext
Error in ReceiveNext: ConnectionReset
Please can you suggest what is wrong in above code snippet?
If you remove or comment out the call to
Close
on theUdpClient
then the program works as expected. Why this is happening I'm not sure, but it could be to do with the Windows loopback networking.This happens with UDP sockets. All you need to do is change socket operating mode before binding it. Use this code in your
Start
method.