Maison  >  Article  >  développement back-end  >  Explication détaillée de l'exemple de code pour la communication synchrone basée sur le protocole UDP de C#

Explication détaillée de l'exemple de code pour la communication synchrone basée sur le protocole UDP de C#

黄舟
黄舟original
2017-03-23 11:38:101961parcourir

Cet article présente principalement le code d'implémentation de synchronisation du protocole UDP basé sur C# L'éditeur pense qu'il est plutôt bon, je vais donc le partager avec vous maintenant et le donner comme référence. Suivons l'éditeur et jetons un coup d'œil

1.Résumé

Résumé de la communication synchrone du protocole UDP basé sur C#.

2. Plateforme expérimentale

Visual Studio 2010

3. Principe expérimental

La différence entre le protocole de transmission UDP et le protocole de transmission TCP peut être trouvée dans les documents pertinents et ne sera pas décrite ici.

4. Exemples

4.1 Utilisation de socket pour implémenter UDP

Puisque UDP est un réseau sans fil Le protocole de connexion. Par conséquent, pour que l'application serveur puisse envoyer et recevoir des paquets UDP, deux choses doivent être faites :

(1) Créer un objet Socket

(2) ) Liez l'objet socket créé au IPEndPoint local.

Après avoir terminé les étapes ci-dessus, le socket créé pourra recevoir des paquets de données UDP entrants sur IPEndPoint, ou envoyer des paquets de données UDP sortants à tout autre appareil du réseau. Lors de la communication via UDP, aucune connexion n'est requise. Comme aucune connexion n'est établie entre les hôtes distants, UDP ne peut pas utiliser les méthodes de socket standard Send() et Receiver()t, mais utilise deux autres méthodes : SendTo() et ReceiverFrom().

La méthode SendTo() spécifie les données à envoyer et l'IPEndPoint de la machine cible. Cette méthode peut être utilisée de plusieurs manières différentes, en fonction de l'application spécifique, mais au moins le paquet et la machine cible doivent être spécifiés. Comme suit :

SendTo(byte[] data,EndPoint Remote)

La méthode ReceiverFrom() est similaire à la méthode SendTo(), mais la manière de déclarer l'objet EndPoint est différente. En utilisant la modification ref, ce qui est transmis n'est pas un objet EndPoint, mais le paramètre est transmis à un objet EndPoint.

L'application UDP n'est pas un véritable serveur et client au sens strict, mais une relation d'égalité, c'est-à-dire qu'il n'y a pas de relation primaire et secondaire. Par souci de simplicité, l'application suivante est toujours appelée serveur UDP.

Code côté serveur :

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];

   //得到本机IP,设置TCP端口号   
   IPEndPoint ip = new IPEndPoint(IPAddress.Any, 8001);
   Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

   //绑定网络地址
   newsock.Bind(ip);

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

   //等待客户机连接
   Console.WriteLine("Waiting for a 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));

   //客户机连接成功后,发送信息
   string welcome = "你好 ! ";

   //字符串与字节数组相互转换
   data = Encoding.ASCII.GetBytes(welcome);

   //发送信息
   newsock.SendTo(data, data.Length, SocketFlags.None, Remote);
   while (true)
   {
    data = new byte[1024];
    //发送接收信息
    recv = newsock.ReceiveFrom(data, ref Remote);
    Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
    newsock.SendTo(data, recv, SocketFlags.None, Remote);
   }
  }

 }
}

Pour que le programme serveur UDP reçoive les messages entrants, le programme doit être lié au port UDP spécifié dans le système local. Ceci est accompli en créant un objet IPEndPoint avec l'adresse IP locale appropriée et le numéro de port UDP approprié. Le serveur UDP dans l'exemple de programme ci-dessus peut recevoir n'importe quel paquet UDP entrant du réseau sur le port 8001.

Le programme client UDP est très similaire au programme serveur.

Comme le client n'a pas besoin d'attendre les données entrantes sur le port UDP spécifié, la méthode Bind() n'est pas utilisée, mais un port UDP désigné aléatoirement par le système lors de l'envoi des données est utilisé, et le même port reçoit le message renvoyé. Lors du développement de produits, spécifiez un ensemble de ports UDP pour le client afin que les programmes serveur et client utilisent le même numéro de port. Le programme client UDP définit d'abord un IPEndPoint et le serveur UDP enverra des paquets de données à cet IPEndPoint. Si vous exécutez un programme serveur UDP sur un périphérique distant, les informations appropriées sur l'adresse IP et le numéro de port UDP doivent être saisies dans la définition IPEndPoint.

Code client :

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;

   //构建TCP 服务器
   Console.WriteLine("This is a Client, host name is {0}", Dns.GetHostName());

   //设置服务IP,设置TCP端口号
   IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8001);

   //定义网络类型,数据连接类型和网络协议UDP
   Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

   string welcome = "你好! ";
   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];
   //对于不存在的IP地址,加入此行代码后,可以在指定时间内解除阻塞模式限制
   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();
  }

 }
}

La logique d'implémentation du code ci-dessus est la suivante : une fois les paramètres pertinents terminés, le serveur envoie d'abord des informations au client, puis le client envoie une chaîne via le clavier, et le serveur Une fois que le client l'a reçu, il l'envoie au client, et ainsi de suite boucles .

4.2 Utilisation de la classe UDPClient pour implémenter

Code côté serveur :

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

public class Custom
{
 // 设置IP,IPV6
 private static readonly IPAddress GroupAddress = IPAddress.Parse("IP地址");
 // 设置端口
 private const int GroupPort = 11000;

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

  UdpClient listener = new UdpClient();

  IPEndPoint groupEP = new IPEndPoint(GroupAddress, GroupPort);

  try
  {
   //IPV6,组播
   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;
 }
}

Code côté client :

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

public class Client
{

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

 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;
 }
}

Ci-dessus Ce qui doit être expliqué à propos du code est :

(1) Le code ci-dessus est un mode multicast basé sur l'adresse IPV6. La diffusion en IPv4 peut entraîner une dégradation des performances du réseau, voire une tempête de diffusion. La notion de diffusion n'existe pas dans IPv6, et est remplacée par multicast et anycast.

(2) Méthode de représentation d'adresse IPV6 :

a) X:X:X:X:X:X:X:X (chaque X représente un nombre hexadécimal à 16 chiffres), non sensible à la casse ;

b) Le 0 initial peut être omis, par exemple, 09C0 peut être écrit comme 9C0, 0000 peut être écrit comme 0

c) Les champs avec des 0 consécutifs peuvent être représentés ; by :: Au lieu de cela, :: ne peut apparaître qu'une seule fois dans l'adresse entière. Par exemple, FF01:0:0:0:0:0:0:1 peut être abrégé en FF01::1.

(3) S'il se présente sous la forme d'un formulaire, il est recommandé d'utiliser ce format, sinon il risque de planter lors de la réception des données.

// 创建一个子线程

   Thread thread = new Thread(
    delegate()
    {
     try
     {
      //在这里写你的代码
     }
     catch (Exception )
     {

     }
    }
   );

   thread.Start();

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn