C#实现UDP通信详解(附带实例)
UDP (User Datagram Protocol的简称)即用户数据报协议,它是网络信息传输的另一种形式。
UDP 通信和 TCP 通信不同,基于 UDP 的信息传递更快,但不提供可靠的保证。使用 UDP 传递数据时,用户无法知道数据能否正确地到达主机,也不能确定到达目的地的顺序是否和发送的顺序相同。
虽然 UDP 是一种不可靠的协议,但如果需要较快地传输信息,并能容忍小的错误,则可以考虑使用 UDP。
基于 UDP 通信的基本模式如下:
因为 UDP 是无连接传输协议,所以不需要在发送和接收数据前建立远程主机连接,但可以选择使用下面两种方法之一来建立默认的远程主机:
UdpClient 类的常用属性、方法及说明如下表所示。
【实例】广播数据报程序。本实例要求主机不断地重复播出节目预报,这样才可以保证加入到同一组的主机随时接收到广播信息。接收者将正在接收的信息放在一个文本框中,并将接收的全部信息放在另一个文本框中。实现步骤如下:
1) 创建广播主机项目 Server(控制台应用程序),首先在 Main 方法中创建 UDP 连接;然后通过 UDP 连接不断向外发送广播信息,代码如下:
2) 创建接收广播项目 Client(Windows 窗体应用程序),在默认窗体中添加两个 Button 控件和两个 TextBox 控件,并且将两个 TextBox 控件设置为多行文本框。单击“开始接收”按钮,系统开始接收主机播出的信息;单击“停止接收”按钮,系统会停止接收广播主机播出的信息,代码如下:

图 1 接收广播程序的运行结果
UDP 通信和 TCP 通信不同,基于 UDP 的信息传递更快,但不提供可靠的保证。使用 UDP 传递数据时,用户无法知道数据能否正确地到达主机,也不能确定到达目的地的顺序是否和发送的顺序相同。
虽然 UDP 是一种不可靠的协议,但如果需要较快地传输信息,并能容忍小的错误,则可以考虑使用 UDP。
基于 UDP 通信的基本模式如下:
- 将数据打包(称为数据包)后发往目的地;
- 接收别人发来的数据包并查看数据包。
C# UdpClient类
在 C# 中,UdpClient 类用于在同步阻止模式下发送和接收无连接 UDP 数据报。因为 UDP 是无连接传输协议,所以不需要在发送和接收数据前建立远程主机连接,但可以选择使用下面两种方法之一来建立默认的远程主机:
- 使用远程主机名和端口号作为参数创建 UdpClient 类的实例;
- 创建 UdpClient 类的实例后调用 Connect 方法。
UdpClient 类的常用属性、方法及说明如下表所示。
属性及方法 | 说明 |
---|---|
Available 属性 | 获取从网络接收的可读取的数据量 |
Client 属性 | 获取或设置基础网络Socket |
BeginReceive 方法 | 从远程主机异步接收数据报 |
BeginSend 方法 | 将数据报异步发送到远程主机 |
Close 方法 | 关闭 UDP 连接 |
Connect 方法 | 建立默认的远程主机 |
EndReceive 方法 | 结束挂起的异步接收 |
EndSend 方法 | 结束挂起的异步发送 |
Receive 方法 | 返回已由远程主机发送的 UDP 数据报 |
Send 方法 | 将 UDP 数据报发送到远程主机 |
C# UDP网络程序实例
根据前面所讲的网络编程的基础知识,以及 UDP 网络编程的特点,下面创建一个广播数据报程序。广播数据报是较新的一种技术,类似于广播电台,广播电台需要在指定的频率上广播信息,收听者也要将收音机调到指定的频率,才可以收听广播内容。【实例】广播数据报程序。本实例要求主机不断地重复播出节目预报,这样才可以保证加入到同一组的主机随时接收到广播信息。接收者将正在接收的信息放在一个文本框中,并将接收的全部信息放在另一个文本框中。实现步骤如下:
1) 创建广播主机项目 Server(控制台应用程序),首先在 Main 方法中创建 UDP 连接;然后通过 UDP 连接不断向外发送广播信息,代码如下:
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace Server { class Program { static UdpClient udp = new UdpClient(); // 创建UdpClient对象 static void Main(string[] args) { // 调用UdpClient对象的Connect方法建立默认的远程主机 udp.Connect("127.0.0.1", 888); while (true) { Thread thread = new Thread(() => { try { // 定义一个字节数组,用来存放发送到远程主机的信息 Byte[] sendBytes = Encoding.Default.GetBytes( "(" + DateTime.Now.ToLongTimeString() + ") 节目预报:八点有大型晚会,请收听"); Console.WriteLine( "(" + DateTime.Now.ToLongTimeString() + ") 节目预报:八点有大型晚会,请收听"); // 调用UdpClient对象的Send方法将UDP数据报发送到远程主机上 udp.Send(sendBytes, sendBytes.Length); } catch (Exception ex) { Console.WriteLine(ex.Message); } }); thread.Start(); // 启动线程 Thread.Sleep(1000); // 线程休眠1秒 } } } }在上面的代码中用到了 Thread 类,该类表示线程类。程序运行结果为:
(11:28:14) 节目预报:八点有大型晚会,请收听
(11:28:14) 节目预报:八点有大型晚会,请收听
(11:28:14) 节目预报:八点有大型晚会,请收听
(11:28:14) 节目预报:八点有大型晚会,请收听
(11:28:14) 节目预报:八点有大型晚会,请收听
2) 创建接收广播项目 Client(Windows 窗体应用程序),在默认窗体中添加两个 Button 控件和两个 TextBox 控件,并且将两个 TextBox 控件设置为多行文本框。单击“开始接收”按钮,系统开始接收主机播出的信息;单击“停止接收”按钮,系统会停止接收广播主机播出的信息,代码如下:
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Windows.Forms; namespace Client { public partial class Form1 : Form { public Form1() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; // 允许跨线程调用控件 } bool flag = true; // 标识是否继续接收数据 UdpClient udp; // UdpClient 对象 Thread thread; // 接收线程 // “开始接收”按钮 private void button1_Click(object sender, EventArgs e) { udp = new UdpClient(888); // 绑定本地端口 888 flag = true; // 任意远程地址、端口皆可接收 IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0); thread = new Thread(() => { while (flag) { try { if (udp.Available <= 0) continue; // 无数据则继续 if (udp.Client == null) return; // 连接为空则退出 byte[] bytes = udp.Receive(ref remoteEP); // 接收 UDP 数据报 string str = Encoding.Default.GetString(bytes); // 字节转字符串 textBox2.Text = "正在接收的信息:\n" + str; // 单行显示最新一条 textBox1.Text += "\n" + str; // 多行追加历史记录 } catch (Exception ex) { MessageBox.Show(ex.Message); // 异常提示 } Thread.Sleep(1000); // 线程休眠 1 秒 } }); thread.Start(); // 启动接收线程 } // “停止接收”按钮 private void button2_Click(object sender, EventArgs e) { flag = false; if (thread != null && thread.ThreadState == ThreadState.Running) thread.Abort(); // 强制终止线程(旧写法,如需优雅退出可改用 CancellationToken) udp.Close(); // 关闭 UDP 连接 } } }程序运行结果如下图所示:

图 1 接收广播程序的运行结果