用户数据报协议 (UDP,User Datagram Protocol) 是一种简单协议,非常适合用于将数据传递到远程主机。由于 UDP 协议是一种无连接协议,因此发送到远程主机的 UDP 数据不一定能到达,也无法保证能以相同顺序到达。使用 UDP 的应用程序必须做好处理丢失、重复和乱序的数据报的准备。
using System;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;namespace SyncServer{public class Program{static void Main(string[] args){Thread thread = new Thread(new ThreadStart(BroadcastIPAddress));thread.IsBackground = true;thread.Name = "#BroadcastIPAddress";thread.Priority = ThreadPriority.Lowest;thread.Start();Console.WriteLine("Start Broadcast");Console.Read();}private static void BroadcastIPAddress(){Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);try{IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, 12593);string machineName = Environment.MachineName;s.MulticastLoopback = true;s.EnableBroadcast = true;var broadCastMessage = Encoding.ASCII.GetBytes(string.Format("{0}:{1}:{2}", machineName, "8080", "SyncServer"));while (true){s.SendTo(broadCastMessage, ip);Thread.Sleep(1000);}}catch (Exception ex){}finally{s.Close();}}}}
using System;using System.Collections.Generic;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Windows;namespace Client{public partial class MainWindow : Window{public MainWindow(){InitializeComponent();Loaded += MainWindow_Loaded;}private void MainWindow_Loaded(object sender, RoutedEventArgs e){Thread thread = new Thread(new ThreadStart(RefreshServers));thread.IsBackground = true;thread.Name = "#RefreshPosServers";thread.Start();}private void RefreshServers(){Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);EndPoint rip = null;try{s.Bind(new IPEndPoint(IPAddress.Any, 12593));rip = (EndPoint)(new IPEndPoint(IPAddress.Any, 0));}catch (Exception ex){return;}try{byte[] buf = new byte[100];int r = 0;while (true){r = s.ReceiveFrom(buf,ref rip);var ip = ((IPEndPoint)rip).Address.ToString();var message = Encoding.Default.GetString(buf, 0, r);if (Dispatcher.CheckAccess()){ReloadData(message);}else{Dispatcher.BeginInvoke(new Action<string>(ReloadData), message);}Thread.Sleep(2000);}}catch (Exception ex)/*Timeout exception*/{System.Diagnostics.Debug.Print(ex.ToString());}}public void ReloadData(object message){txtMessage.Text += message + "\r\n";}}}
下图为演示效果:
