WPF-25 UDP协议

用户数据报协议 (UDP,User Datagram Protocol) 是一种简单协议,非常适合用于将数据传递到远程主机。由于 UDP 协议是一种无连接协议,因此发送到远程主机的 UDP 数据不一定能到达,也无法保证能以相同顺序到达。使用 UDP 的应用程序必须做好处理丢失、重复和乱序的数据报的准备。

我们来模拟一个简单业务场景,比如我们将服务器端 电脑名称/端口/服务名广播到12593端口,我们新建一个Console应用程序作为SyncServer服务: .
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();            }        }    }}
我们新建WPF客户端应用程序命名为Client,在12593端口上接收信息:
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";        }    }}
上面代码我们创建Socket对象绑定到12593端口来接收广播信息,Dispatcher.CheckAccess()代码表示是否与UI线程关联,如果关联可以直接调用UI上控件,否则需要通过Dispatcher.BeginInvoke方法访问UI元素。

下图为演示效果:

WPF-25 UDP协议

传输层有两个主要协议:面向连接TCP,TCP则是可靠传输协议,在传输过程中保证了消息的可靠性和有序性。无连接UDP,UDP只管将信息发出去,而不管对方是否收到该信息所以不可靠。在速度方面TCP要比UDP慢,因为TCP要创建连接以及保证消息的可靠性和有序性,需要额外做很多事情,UDP则不用。在重量级方面TCP则比UDP更重,因为TCP报头要比UDP多。UDP应用场景主要有视频会议、语音聊天等速度快,而准确性相对较低的应用场景。