In diesem Artikel wird hauptsächlich der Synchronisierungsimplementierungscode des UDP-Protokolls basierend auf C# vorgestellt. Der Herausgeber findet ihn recht gut, daher werde ich ihn jetzt mit Ihnen teilen und als Referenz verwenden. Folgen wir dem Editor und werfen wir einen Blick darauf.
2. Experimentelle Plattform
Visual Studio 2010
3. Experimentelles Prinzip
Der Unterschied zwischen UDP-Übertragungsprotokoll und TCP-Übertragungsprotokoll ist in den entsprechenden Dokumenten zu finden und wird hier nicht beschrieben.
4. Beispiele
4.1 Verwendung von Socket zur Implementierung von UDPDa es sich bei UDP um eine drahtlose Verbindung handelt Das Verbindungsprotokoll. Damit die Serveranwendung UDP-Pakete senden und empfangen kann, müssen daher zwei Dinge getan werden:
(1) Erstellen Sie ein Socket-Objekt(2 ) Binden Sie das erstellte Socket-Objekt an den lokalen IPEndPoint.
Nach Abschluss der oben genannten Schritte kann der erstellte Socket eingehende UDP-Datenpakete auf IPEndPoint empfangen oder ausgehende UDP-Datenpakete an jedes andere Gerät im Netzwerk senden. Bei der Kommunikation über UDP ist keine Verbindung erforderlich. Da zwischen Remote-Hosts keine Verbindung hergestellt wird, kann UDP nicht die Standard-Socket-Methoden Send() und Receive() verwenden, sondern zwei andere Methoden: SendTo() und ReceiveFrom().
Die SendTo()-Methode gibt die zu sendenden Daten und den IPEndPoint des Zielcomputers an. Abhängig von der konkreten Anwendung kann diese Methode auf verschiedene Arten verwendet werden, es müssen jedoch mindestens das Paket und die Zielmaschine angegeben werden. Wie folgt:
Die Methode „ReceiveFrom()“ ähnelt der Methode „SendTo()“, die Art und Weise, das EndPoint-Objekt zu deklarieren, ist jedoch unterschiedlich. Bei der Ref-Änderung wird kein EndPoint-Objekt übergeben, sondern der Parameter wird an ein EndPoint-Objekt übergeben.
SendTo(byte[] data,EndPoint Remote)
Da der Client nicht auf eingehende Daten am angegebenen UDP-Port warten muss, wird daher nicht die Bind()-Methode verwendet, sondern ein vom System beim Senden von Daten zufällig festgelegter UDP-Port verwendet und derselbe Port empfängt die zurückgegebene Nachricht. Geben Sie bei der Entwicklung von Produkten einen Satz UDP-Ports für den Client an, damit die Server- und Client-Programme dieselbe Portnummer verwenden. Das UDP-Client-Programm definiert zunächst einen IPEndPoint und der UDP-Server sendet Datenpakete an diesen IPEndPoint. Wenn Sie ein UDP-Serverprogramm auf einem Remote-Gerät ausführen, müssen die entsprechenden Informationen zur IP-Adresse und UDP-Portnummer in die IPEndPoint-Definition eingegeben werden.
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); } } } }
Die Implementierungslogik des obigen Codes lautet: Nachdem die relevanten Einstellungen abgeschlossen sind, sendet der Server zuerst Informationen an den Client und dann sendet der Client eine Zeichenfolge über die Tastatur und den Server. Nachdem der Client es empfangen hat, sendet er es an den Client usw.
Schleifen
4.2 Verwendung der UDPClient-Klasse zur Implementierung von
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(); } } }
Oben Was über den Code erklärt werden muss, ist:
(1) Der obige Code ist ein Multicast-Modus basierend auf der IPV6-Adresse. Broadcast in IPv4 kann zu einer Verschlechterung der Netzwerkleistung oder sogar zu einem Broadcast-Sturm führen. Das Broadcast-Konzept existiert in IPv6 nicht und wird durch Multicast und Anycast ersetzt.
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; } }
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; } }
b) Die führende 0 kann weggelassen werden, zum Beispiel kann 09C0 als 9C0 geschrieben werden, 0000 kann als 0 geschrieben werden;
c) Felder mit aufeinanderfolgenden Nullen können dargestellt werden von :: Stattdessen kann :: nur einmal in der gesamten Adresse vorkommen. Beispielsweise kann FF01:0:0:0:0:0:0:1 als FF01::1 abgekürzt werden.
(3) Wenn es sich um ein Formular handelt, wird empfohlen, dieses Format zu verwenden, da es sonst beim Empfang von Daten zum Absturz kommen kann.
Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung des Beispielcodes für synchrone Kommunikation basierend auf dem UDP-Protokoll von C#. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!