C# UDP Packet Send & Receive

cnetworkingsocketsudp

I'm trying to figure out how I can send & receive data via the UDP protocol using C# as a client, and having a JS server running that will transmit a "response" packet for testing purposes.

Below is the UDP class that I made for testing, it's simply just 2 threads:
One that read the received data from UDP and another thread for sending data.

using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using System.Net.Sockets;

using System.Threading;

namespace UDPTesting {

    class UDPHandler {

        private int receivePort, sendPort;
        private string serverIP;
        private IPEndPoint sendEndPoint, receiveEndPoint;

        public UDPHandler(string serverIP, int receivePort, int sendPort) {
            this.serverIP = serverIP;
            this.receivePort = receivePort;
            this.sendPort = sendPort;
            this.sendEndPoint = new IPEndPoint(IPAddress.Parse(this.serverIP), this.sendPort);
            this.receiveEndPoint = new IPEndPoint(IPAddress.Parse(this.serverIP), this.receivePort);
            this.readerUdpClient();
            this.senderUdpClient();
        }

        void readerUdpClient() {
            UdpClient readerClient = new UdpClient();
            IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Any, 3000);
            readerClient.Client.Bind(localEndpoint);          //Tried both Connect and Bind
            //readerClient.Connect(this.receiveEndPoint);
            Thread t = new Thread(() => {
                Console.WriteLine("Awaiting data from server...");
                var remoteEP = new IPEndPoint(IPAddress.Any, 3000);
                byte[] bytesReceived = readerClient.Receive(ref remoteEP);
                //The above throws:     System.InvalidOperationException: 'You must call the Bind method before performing this operation'
                Console.WriteLine("Received data from " + remoteEP.ToString());
            });
            t.Start();
        }

        void senderUdpClient() {
            UdpClient senderClient = new UdpClient();
            senderClient.Connect(this.sendEndPoint);
            string sendString = "1;2;3";
            byte[] bytes = toBytes(sendString);
            Thread t = new Thread(() => {
                while (true) {
                    senderClient.Send(bytes, bytes.Length);
                    Thread.Sleep(1000);
                }
            });
            t.Start();
        }

        public byte[] toBytes(string text) {
            return Encoding.UTF8.GetBytes(text);
        }

        public string fromBytes(byte[] bytes) {
            return Encoding.UTF8.GetString(bytes);
        }

    }
}

Additionally my "main" for my program is this:

using System;
using System.Threading;

namespace UDPTesting {

    class Program {

        static void Main(string[] args) {
            string serverIP = "46.101.102.243";
            int sendPort = 41234;
            int receivePort = 3000;
            UDPHandler handler = new UDPHandler(serverIP, receivePort, sendPort);
        }

    }

}

How can I read the response that the server sends in the client, at the same time as I send data from the client to the server?

We tested it individually:

1) Sending a UDP packet from client -> server works, as I can see that the server receives the packet.

2) Sending a UDP packet from server -> client works, as I can see the client receives the packet.

3) When the client tries to send and read simultaneously, it will send data to the server, but will not read the response.

Any help would be greatly appreciated!

Best Answer

Your receiving function should work like this

void readerUdpClient()
{
    new Thread(() => {
        UdpClient readerClient = new UdpClient(receivePort);  
        Console.WriteLine("Awaiting data from server...");
        var remoteEP = new IPEndPoint(IPAddress.Any, 0);
        byte[] bytesReceived = readerClient.Receive(ref remoteEP);
        Console.WriteLine($"Received {bytesReceived.Length} bytes from {remoteEP}");
    }).Start();
}

The UdpClient constructor that takes a port automatically binds the local end point for you.

Related Topic