Implementation code of synchronous communication of UDP protocol based on C

  • 2021-12-04 19:34:51
  • OfStack

1. Summary

Summarize the synchronous communication of UDP protocol based on C #.

2. Experimental platform

Visual Studio 2010

3. Experimental principle

The difference between UDP transmission protocol and TCP transmission protocol can be consulted in relevant documents, which will not be repeated here.

4. Examples

4.1 Implementation of UDP with socket

Because UDP is a connectionless protocol. Therefore, in order for the server application to be able to send and receive UDP packets, two things need to be done:

(1) Create an Socket object;

(2) Bind the created socket object to the local IPEndPoint.

After completing the above steps, the socket created can receive incoming UDP packets on IPEndPoint or send outgoing UDP packets to any other device in the network. When communicating using UDP, no connection is required. Because there is no connection between hosts in different places, UDP cannot use the standard Send () and Receive () t socket methods, but uses two other methods: SendTo () and ReceiveFrom ().

The SendTo () method specifies the data to send and the IPEndPoint of the target machine. There are many different ways to use this method, which can be selected according to the specific application, but at least the data packet and target machine should be specified. As follows:


SendTo(byte[] data,EndPoint Remote)

The ReceiveFrom () method is similar to the SendTo () method, but not in the same way as the EndPoint object declaration. With the ref modification, instead of passing an EndPoint object, the parameters are passed to an EndPoint object.

The UDP application is not a true server and client in the strict sense, but an equal relationship, that is, there is no primary and secondary relationship. For simplicity, the following application is still called UDP server.

Server-side code:


using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDP
{
 class Program
 {
  static void Main(string[] args)
  {
   int recv;
   byte[] data = new byte[1024];

   // Get this machine IP , setting TCP Port number    
   IPEndPoint ip = new IPEndPoint(IPAddress.Any, 8001);
   Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

   // Bind network address 
   newsock.Bind(ip);

   Console.WriteLine("This is a Server, host name is {0}", Dns.GetHostName());

   // Waiting for client connection 
   Console.WriteLine("Waiting for a client");

   // Get the client IP
   IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
   EndPoint Remote = (EndPoint)(sender);
   recv = newsock.ReceiveFrom(data, ref Remote);
   Console.WriteLine("Message received from {0}: ", Remote.ToString());
   Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));

   // After the client connects successfully, send information 
   string welcome = " How do you do  ! ";

   // String and byte array conversion 
   data = Encoding.ASCII.GetBytes(welcome);

   // Send a message 
   newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
   while (true)
   {
    data = new byte[1024];
    // Send and receive information 
    recv = newsock.ReceiveFrom(data, ref Remote);
    Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
    newsock.SendTo(data, recv, SocketFlags.None, Remote);
   }
  }

 }
}

For UDP server programs that receive incoming, the program must be bound to the UDP port specified on the local system. This allows you to create an IPEndPoint object with the appropriate local IP address and the appropriate UDP port number. The UDP server in the example above can receive any incoming UDP packets from the network on port 8001.

The UDP client program is very similar to the server program.

Because the client does not need to wait for incoming data at the specified UDP port, instead of using the Bind () method, it uses one UDP port randomly specified by the system when the data is sent, and uses the same port to receive the returned message. When developing a product, specify a set of UDP ports for the client so that the server and client programs use the same port number. The UDP client program first defines an IPEndPoint to which the UDP server will send packets. If the UDP server program is running on a remote device, the appropriate IP address and UDP port number information must be entered in the IPEndPoint definition.

Client code:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace UDPClient
{
 class Program
 {
  static void Main(string[] args)
  {
   byte[] data = new byte[1024];
   string input, stringData;

   // Build TCP  Server 
   Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName());

   // Set up services IP , setting TCP Port number 
   IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8001);

   // Define network types, data connection types, and network protocols UDP
   Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

   string welcome = " How do you do ! ";
   data = Encoding.ASCII.GetBytes(welcome);
   server.SendTo(data, data.Length, SocketFlags.None, ip);
   IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
   EndPoint Remote = (EndPoint)sender;

   data = new byte[1024];
   // For nonexistent IP Address, after adding this line of code, you can release the blocking mode restriction within the specified time 
   int recv = server.ReceiveFrom(data, ref Remote);
   Console.WriteLine("Message received from {0}: ", Remote.ToString());
   Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
   while (true)
   {
    input = Console.ReadLine();
    if (input == "exit")
     break;
    server.SendTo(Encoding.ASCII.GetBytes(input), Remote);
    data = new byte[1024];
    recv = server.ReceiveFrom(data, ref Remote);
    stringData = Encoding.ASCII.GetString(data, 0, recv);
    Console.WriteLine(stringData);
   }
   Console.WriteLine("Stopping Client.");
   server.Close();
  }

 }
}

The implementation logic of the above code is: after the relevant settings are completed, the server first sends information to the client, and then the client sends a string through the keyboard, and then the server receives it and sends it to the client, so the cycle.

4.2 Implementation with UDPClient class

Server-side code:


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

public class Custom
{
 //  Settings IP , IPV6
 private static readonly IPAddress GroupAddress = IPAddress.Parse("IP Address ");
 //  Setting Port 
 private const int GroupPort = 11000;

 private static void StartListener()
 {
  bool done = false;

  UdpClient listener = new UdpClient();

  IPEndPoint groupEP = new IPEndPoint(GroupAddress, GroupPort);

  try
  {
   //IPV6 Multicast 
   listener.JoinMulticastGroup(GroupAddress);

   listener.Connect(groupEP);

   while (!done)
   {
    Console.WriteLine("Waiting for broadcast");

    byte[] bytes = listener.Receive(ref groupEP);

    Console.WriteLine("Received broadcast from {0} :\n {1}\n", groupEP.ToString(), Encoding.ASCII.GetString(bytes, 0, bytes.Length));
   }

   listener.Close();

  }
  catch (Exception e)
  {
   Console.WriteLine(e.ToString());
  }

 }

 public static int Main(String[] args)
 {
  StartListener();

  return 0;
 }
}

Client code:


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

public class Client
{

 private static IPAddress GroupAddress = IPAddress.Parse("IP Address ");

 private static int GroupPort = 11000;

 private static void Send(String message)
 {
  UdpClient sender = new UdpClient();

  IPEndPoint groupEP = new IPEndPoint(GroupAddress, GroupPort);

  try
  {
   Console.WriteLine("Sending datagram : {0}", message);

   byte[] bytes = Encoding.ASCII.GetBytes(message);

   sender.Send(bytes, bytes.Length, groupEP);

   sender.Close();

  }
  catch (Exception e)
  {
   Console.WriteLine(e.ToString());
  }

 }

 public static int Main(String[] args)
 {
  Send(args[0]);

  return 0;
 }
}

What the above code needs to explain is:

(1) The above code is based on IPV6 address multicast mode. Broadcast in IPv4 (broadcast) can cause network performance degradation or even broadcast storm (ES116storm). In IPv6, the concept of broadcast does not exist, but multicast (multicast) and arbitrcast (anycast) are replaced.

(2) IPV6 address representation method:

a) X: X: X: X: X: X: X: X (each X represents a 16-digit hexadecimal digit), case-insensitive;

b) The 0 at the head of the row can be omitted, for example, 09C0 can be written as 9C0, and 0000 can be written as 0;

c) Continuous 0 fields can be replaced by::, but:: can only appear once in the whole address. For example, FF01: 0: 0: 0: 0: 0: 0: 1 can be abbreviated to FF01:: 1.

(3) It is recommended to use this format if it is in the form of form, otherwise it may crash when receiving data.


//  Create 1 Sub-thread 

   Thread thread = new Thread(
    delegate()
    {
     try
     {
      // Write your code here 
     }
     catch (Exception )
     {

     }
    }
   );

   thread.Start();


Related articles: