[c#] Simple UDP example to send and receive data from same socket

For some reason I am having a hard time sending and receiving data from the same socket. Anyways here is my client code:

var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening (testing localy)
client.Connect(ep); 

// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);

// then receive data
var receivedData = client.Receive(ref ep);  // Exception: An existing connection was forcibly closed by the remote host

Basically I want to create a protocol where I send a udp packet and then I expect a response. Just like the HTTP protocol for every request there is a response. This code works if the server is on a different computer. There might be the case where the server and client are on the same computer though.

Here is the server:

UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);

while (true)
{
    var groupEP = new IPEndPoint(IPAddress.Any, 11000); // listen on any port
    var data = udpServer.Receive(ref groupEP);
    udpServer.Send(new byte[] { 1 }, 1); // if data is received reply letting the client know that we got his data          
}

Edit

the reason why I cannot use tcp is because sometimes the client is behind a NAT (router) and it is simpler to do UDP hole punching than TCP.


Solution:

thanks to markmnl answer here is my code:

Server:

UdpClient udpServer = new UdpClient(11000);

while (true)
{
    var remoteEP = new IPEndPoint(IPAddress.Any, 11000); 
    var data = udpServer.Receive(ref remoteEP); // listen on port 11000
    Console.Write("receive data from " + remoteEP.ToString());
    udpServer.Send(new byte[] { 1 }, 1, remoteEP); // reply back
}

Client code:

var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening
client.Connect(ep);

// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);

// then receive data
var receivedData = client.Receive(ref ep);

Console.Write("receive data from " + ep.ToString());

Console.Read();

This question is related to c# udp

The answer is


I'll try to keep this short, I've done this a few months ago for a game I was trying to build, it does a UDP "Client-Server" connection that acts like TCP, you can send (message) (message + object) using this. I've done some testing with it and it works just fine, feel free to modify it if needed.


here is my soln to define the remote and local port and then write out to a file the received data, put this all in a class of your choice with the correct imports

    static UdpClient sendClient = new UdpClient();
    static int localPort = 49999;
    static int remotePort = 49000;
    static IPEndPoint localEP = new IPEndPoint(IPAddress.Any, localPort);
    static IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), remotePort);
    static string logPath = System.AppDomain.CurrentDomain.BaseDirectory + "/recvd.txt";
    static System.IO.StreamWriter fw = new System.IO.StreamWriter(logPath, true);


    private static void initStuff()
    {
      
        fw.AutoFlush = true;
        sendClient.ExclusiveAddressUse = false;
        sendClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        sendClient.Client.Bind(localEP);
        sendClient.BeginReceive(DataReceived, sendClient);
    }

    private static void DataReceived(IAsyncResult ar)
    {
        UdpClient c = (UdpClient)ar.AsyncState;
        IPEndPoint receivedIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
        Byte[] receivedBytes = c.EndReceive(ar, ref receivedIpEndPoint);
        fw.WriteLine(DateTime.Now.ToString("HH:mm:ss.ff tt") +  " (" + receivedBytes.Length + " bytes)");

        c.BeginReceive(DataReceived, ar.AsyncState);
    }


    static void Main(string[] args)
    {
        initStuff();
        byte[] emptyByte = {};
        sendClient.Send(emptyByte, emptyByte.Length, remoteEP);
    }