用户数据报协议 (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元素。
下图为演示效果:
传输层有两个主要协议:面向连接TCP,TCP则是可靠传输协议,在传输过程中保证了消息的可靠性和有序性。无连接UDP,UDP只管将信息发出去,而不管对方是否收到该信息所以不可靠。在速度方面TCP要比UDP慢,因为TCP要创建连接以及保证消息的可靠性和有序性,需要额外做很多事情,UDP则不用。在重量级方面TCP则比UDP更重,因为TCP报头要比UDP多。UDP应用场景主要有视频会议、语音聊天等速度快,而准确性相对较低的应用场景。
技术群:添加小编微信并备注进群
小编微信:mm1552923
公众号:dotNet编程大全