Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connection reset on receiving packet in UDP server

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?

like image 609
Hemant Avatar asked Apr 26 '12 11:04

Hemant


People also ask

Can UDP send and receive on same socket?

TCP vs UDP Once connected, a TCP socket can only send and receive to/from the remote machine. This means that you'll need one TCP socket for each client in your application. UDP is not connection-based, you can send and receive to/from anyone at any time with the same socket.

What would cause Connection reset by peer?

The error message "Connection reset by peer" appears, if the web services client was waiting for a SOAP response from the remote web services provider and the connection was closed prematurely. One of the most common causes for this error is a firewall in the middle closing the connection.

How do you handle Connection reset by peer?

Connection Reset by Peer with a Socket Write ErrorType “ping” along with the server's address. Execute the command. Run “tracert” and the server address to see if the request is successful. Execute “telnet” and enter the server address to see if the local machine ports are open.

What is the meaning of connection closed by peer?

The “ssh_exchange_identification: read: Connection reset by peer” error indicates that the remote machine abruptly closed the Transition Control Protocol (TCP) stream. In most instances, a quick reboot of a remote server might solve a temporary outage or connectivity issue.


2 Answers

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.

mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 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);
like image 135
Maciej Avatar answered Nov 14 '22 23:11

Maciej


If you remove or comment out the call to Close on the UdpClient 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.

like image 22
Nick Avatar answered Nov 14 '22 23:11

Nick