Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple UDP example to send and receive data from same socket

Tags:

c#

udp

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(); 
like image 231
Tono Nam Avatar asked Nov 18 '13 02:11

Tono Nam


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.

Can you send and receive data on the same socket?

You can send and receive on the same socket at the same time (via multiple threads). But the send and receive may not actually occur simultaneously, since one operation may block the other from starting until it's done.

How do you send and receive UDP packets?

To receive packets from all the sending hosts, specify the remote IP address as 0.0. 0.0 . Match the port number specified in the Local IP Port parameter with the remote port number of the sending host. You can choose to receive the UDP packets in blocking or non-blocking mode.

Can multiple clients send data to the same UDP socket used by a server?

You could create a new UDP socket, bind() it to a different port, and then instruct the client to start sending traffic to the new socket's port instead of the usual one; but note that there isn't really any advantage to be gained by doing that.


1 Answers

(I presume you are aware that using UDP(User Datagram Protocol) does not guarantee delivery, checks for duplicates and congestion control and will just answer your question).

In your server this line:

var data = udpServer.Receive(ref groupEP); 

re-assigns groupEP from what you had to a the address you receive something on.

This line:

udpServer.Send(new byte[] { 1 }, 1);  

Will not work since you have not specified who to send the data to. (It works on your client because you called connect which means send will always be sent to the end point you connected to, of course we don't want that on the server as we could have many clients). I would:

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

Also if you have server and client on the same machine you should have them on different ports.

like image 73
markmnl Avatar answered Oct 10 '22 10:10

markmnl