首页 > 编程笔记 > C#笔记 阅读:1

C#实现UDP通信详解(附带实例)

UDP (User Datagram Protocol的简称)即用户数据报协议,它是网络信息传输的另一种形式。

UDP 通信和 TCP 通信不同,基于 UDP 的信息传递更快,但不提供可靠的保证。使用 UDP 传递数据时,用户无法知道数据能否正确地到达主机,也不能确定到达目的地的顺序是否和发送的顺序相同。

虽然 UDP 是一种不可靠的协议,但如果需要较快地传输信息,并能容忍小的错误,则可以考虑使用 UDP。

基于 UDP 通信的基本模式如下:

C# UdpClient类

在 C# 中,UdpClient 类用于在同步阻止模式下发送和接收无连接 UDP 数据报。

因为 UDP 是无连接传输协议,所以不需要在发送和接收数据前建立远程主机连接,但可以选择使用下面两种方法之一来建立默认的远程主机:
UdpClient 类的常用属性、方法及说明如下表所示。

表: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 接收广播程序的运行结果

相关文章