【代码】C#下UDP传输模板

Posted on Posted in 计算机2,284 views

注:该代码创建于2013.12月,是C#下UDP学习时写的代码实例,主要是UdpClient的学习使用。

//2013-12-05 xia-evan

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net; 
//添加命名空间
using System.Net.Sockets;
using System.Threading;

namespace UDP
{
    public partial class UDPFM : Form
    {
        public UDPFM()
        {
            InitializeComponent();
        }
        /*UdpClient的属性 
         * Active          获取或设置一个值,该值指示是否已建立默认远程主机。
         * udpAvailable    获取从网络接收的可读取的数据量。
         * udpClient       获取或设置基础网络 Socket。
         * udpDontFragment 
         *   获取或设置 Boolean 值,指定 UdpClient 是否允许对 Internet 协议 (IP) 数据报进行分段。
         * udpEnableBroadcast     获取或设置 Boolean 值,指定 UdpClient 是否可以发送或接收广播数据包。
         * udpExclusiveAddressUse 获取或设置 Boolean 值,指定 UdpClient 是否只允许一个客户端使用端口。
         * udpMulticastLoopback   获取或设置 Boolean 值,指定是否将输出多路广播数据包传递给发送应用程序。
         * udpTtl                 
         *   获取或设置一个值,指定由 UdpClient 发送的 Internet 协议 (IP) 数据包的生存时间 (TTL)。
         *
         *UdpClient的方法
         * AllowNatTraversal      启用或禁用针对 UdpClient 实例的网络地址转换 (NAT) 遍历。
         * BeginReceive           从远程主机异步接收数据报。
         * BeginSend(Byte[], Int32, AsyncCallback, Object)  
         *   将数据报异步发送到远程主机。 先前已通过调用 Connect 指定目标。
         * BeginSend(Byte[], Int32, IPEndPoint, AsyncCallback, Object)    
         *   将数据报异步发送到目标。 目标由 EndPoint 指定。
         * BeginSend(Byte[], Int32, String, Int32, AsyncCallback, Object) 
         *   将数据报异步发送到目标。 目标由主机名和端口号指定。
         * Close                   关闭 UDP 连接。
         * Connect(IPEndPoint)     使用指定的网络终结点建立默认远程主机。
         * Connect(IPAddress, Int32)  使用指定的 IP 地址和端口号建立默认远程主机。
         * Connect(String, Int32)     使用指定的主机名和端口号建立默认远程主机。
         * Dispose                 释放由 UdpClient 占用的非托管资源,还可以另外再释放托管资源。
         * DropMulticastGroup(IPAddress)  退出多路广播组。
         * DropMulticastGroup(IPAddress, Int32) 退出多路广播组。
         * EndReceive              结束挂起的异步接收。
         * EndSend                 结束挂起的异步发送。
         * Equals(Object) 确定指定的对象是否等于当前对象。 (继承自 Object。)
         * Finalize       允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。 (继承自 Object。)
         * GetHashCode    作为默认哈希函数。 (继承自 Object。)
         * GetType        获取当前实例的 Type。 (继承自 Object。)
         * JoinMulticastGroup(IPAddress)        将 UdpClient 添加到多路广播组。
         * JoinMulticastGroup(Int32, IPAddress) 将 UdpClient 添加到多路广播组。
         * JoinMulticastGroup(IPAddress, Int32) 
         *   将指定的生存时间 (TTL) 与 UdpClient 一起添加到多路广播组。
         * JoinMulticastGroup(IPAddress, IPAddress) 将 UdpClient 添加到多路广播组。
         * MemberwiseClone  创建当前 Object 的浅表副本。 (继承自 Object。)
         * Receive          返回已由远程主机发送的 UDP 数据报。
         * ReceiveAsync     异步返回已由远程主机发送的 UDP 数据报。
         * Send(Byte[], Int32)   将 UDP 数据报发送到远程主机。
         * Send(Byte[], Int32, IPEndPoint)    将 UDP 数据报发送到位于指定远程终结点的主机。
         * Send(Byte[], Int32, String, Int32) 将 UDP 数据报发送到指定的远程主机上的指定端口。
         * SendAsync(Byte[], Int32)             将 UDP 数据报异步发送到远程主机。
         * SendAsync(Byte[], Int32, IPEndPoint) 将 UDP 数据报异步发送到远程主机。
         * SendAsync(Byte[], Int32, String, Int32)    将 UDP 数据报异步发送到远程主机。 
         */
        
        //定义网络端点
        private IPEndPoint ServerEndPoint = null;                                    
        //创建网络服务,也就是UDP的Sockets 
        private UdpClient udp = new UdpClient();                                     
        //创建网络服务,也就是UDP的Sockets作为一个独立的发送,如果服务器和客户端都有可以共用一个就行  
        private UdpClient udp_client = new UdpClient();                             
        private bool active = false;
        
        //创建一个线程
        private Thread thdUdp = null;                                               
        //定义了一个托管方法  
        public delegate void DataArrivalEventHandler(string str);                    
        #region 网络连接
     
        //监听
        protected void Listener(int port)   
        {               
            //将IP地址和端口号以网络端点存储,IPAddress.Any监听所有IP
            ServerEndPoint = new IPEndPoint(IPAddress.Any, port); 
            //如果已经存在则先关闭  
            if (udp != null)
                udp.Close();
            try
            {                                          
                //创建一个新的端口号
                udp = new UdpClient(port);                          
                //接收缓冲区大小
                udp.Client.ReceiveBufferSize = 1000000000;
                //发送缓冲区大小
                udp.Client.SendBufferSize = 1000000000;                      
                active = true;
                //创建一个线程
                thdUdp = new Thread(new ThreadStart(GetUDPData));                            
                //执行当前线程
                thdUdp.Start();                                              
            }
            catch (Exception e)
            {
                if (udp != null)
                    udp.Close();
                if (thdUdp != null)
                {
                    Thread.Sleep(30);
                    thdUdp.Abort();
                }
                MessageBox.Show(e.ToString());                      
            }
        }
        
        //获取当前接收的消息<线程函数>
        private void GetUDPData()
        {
            while (active)
            {
                try
                {
                    //将获取的远程消息转换成二进制流
                    byte[] Data = udp.Receive(ref ServerEndPoint);
                    //交换信息的两个线程用的Encoding编码必须一致
                    string str = Encoding.ASCII.GetString(Data);  
                    //--------------------------------------------------
                    //里面可以创建新线程
                    //--------------------------------------------------
                    DataArrivalEventHandler showDate = new DataArrivalEventHandler(MessageAdd);
                    object[] objs = new object[1];
                    objs[0] = str;
                    Invoke(showDate, objs); 
                    Thread.Sleep(0);
                }
                catch { }
            }
        }
        
        //将接收到的消息放入List
        public void MessageAdd(string str)
        {
            lsb_message.Items.Add( DateTime.Now.ToString() + "\t" + str);  
        }
        
        //发送信息(与前面的没关系)
        public void Send(string text, string ipAdr, int port)
        {
            //接收方的IP地址 ,IPAddress.Any广播所有
            IPAddress ip = IPAddress.Parse(ipAdr);
            //对方打开监听的端口 
            int Port = port;  
            //将当前要发送的信息转换成二进制流  
            byte[] Data = Encoding.ASCII.GetBytes(text);
            IPEndPoint server = new IPEndPoint(ip, Port);
            //udp_client.Connect(server); 
            //这句就是发送语句,如果服务器和客户端都有可以共用一个udp就行
            udp_client.Send(Data, Data.Length, server);                     
        }
        
        //关闭监听
        private void CloseSocket()
        {
            if (udp != null)
                udp.Close(); 
            if (thdUdp != null)
            {
                Thread.Sleep(30);
                thdUdp.Abort();
            }
        } 
       
        #endregion
        
        //开始监听
        private void btn_KS_Click(object sender, EventArgs e)
        {
            btn_KS.Enabled = false;
            btn_JS.Enabled = true;
            Listener(2000);
        }
        
        //结束监听
        private void btn_JS_Click(object sender, EventArgs e)
        {
            btn_KS.Enabled = true;
            btn_JS.Enabled = false;
            CloseSocket();
        }
        
        //发送信息
        private void btn_FS_Click(object sender, EventArgs e)
        {
            Send(txb_message.Text, "127.0.0.1", 2000);
        }
        
        //退出程序
        private void UDPFM_FormClosing(object sender, FormClosingEventArgs e)
        {
            CloseSocket();
            if (udp_client != null)
                udp_client.Close();
            System.Environment.Exit(0);//Application.Exit(); 
        }
    }
}


转载标明出处:https://blog.evanxia.com/2015/12/229