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 接收广播程序的运行结果
ICP备案:
公安联网备案: