C# UDPClient类(通过UdpClient类实现局域网UDP通讯)

来源:互联网 发布:nike海外代购淘宝店 编辑:程序博客网 时间:2024/06/05 08:16

1、UDP(User Data Protocol,用户数据报协议)
(1) UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。
(2) 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。
(3) UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。
(4) 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。
(5)UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。
(6)UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。
我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。
a.每个udp包的最大大小是多少?
65507 约等于 64K

b.为什么最大是65507?
因为udp包头有2个byte用于记录包体长度. 2个byte可表示最大值为: 2^16-1=64K-1=65535
udp包头占8字节, ip包头占20字节, 65535-28 = 65507

c.如果要发送的udp报文大于65507怎么办?
需要在应用层由开发者自己分片发送. 分片的粒度最大65507字节. 系统的sendto函数是不支持大于65507字节的单包发送的.
2、C#UDPClient类实现的简单通讯程序
发送和接收数据控件:richTextBox
代码:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Net;using System.Net.Sockets;using System.Threading;namespace UDPClient_Server{    public partial class UDPForm : Form    {        UdpClient udpClient;        IPEndPoint locatePoint;        public UDPForm()        {            InitializeComponent();        }        private void UDPForm_Load(object sender, EventArgs e)        {            txtLocateIP.Text = getIPAddress();            txtRemoteIP.Text = getIPAddress();            //禁止夸线程监视            Control.CheckForIllegalCrossThreadCalls = false;//这种方法不好,只是方便,不提倡        }        /// <summary>        ///         /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void btnServer_Click(object sender, EventArgs e)        {           // btnClient.Enabled = false;            if (udpClient != null)                return;            IPAddress locateIp = IPAddress.Parse(txtLocateIP.Text);            locatePoint = new IPEndPoint(locateIp, Convert.ToInt32(txtLocatePort.Text));            udpClient = new UdpClient(locatePoint);            //监听创建好后,就开始接收信息,并创建一个线程            Thread th = new Thread(Receive);            th.IsBackground = true;            th.Start();        }        /// <summary>        /// 接收线程方法        /// </summary>        void Receive()        {            byte[] recBuffer;            //远端IP            IPEndPoint remotePoint = new IPEndPoint(IPAddress.Any, 0);            while (true)            {                try                {                    recBuffer = udpClient.Receive(ref remotePoint);                    if (recBuffer != null)                    {                        string str = System.Text.Encoding.UTF8.GetString(recBuffer,0,recBuffer.Length);                        rtxtRec.AppendText(remotePoint.ToString()+str+"\r\n");                    }                }                catch (Exception e)                {                    MessageBox.Show(e.ToString());                }            }        }        private void btnSend_Click(object sender, EventArgs e)        {            if (string.IsNullOrWhiteSpace(rtxtSend.Text.Trim()))                return;            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(rtxtSend.Text.Trim());            IPAddress remoteIp = IPAddress.Parse(txtLocateIP.Text);            IPEndPoint remotePoint = new IPEndPoint(remoteIp, Convert.ToInt32(txtRemotePort.Text));            udpClient.Send(buffer, buffer.Length, remotePoint);        }        /// <summary>        /// 获取本地IP的方法        /// </summary>        /// <returns></returns>        private string getIPAddress()        {            //获取本地所有IP地址            IPHostEntry ipe = Dns.GetHostEntry(Dns.GetHostName());            IPAddress[] ip = ipe.AddressList;            for (int i = 0; i < ip.Length; i++)            {                if (ip[i].AddressFamily.ToString().Equals("InterNetwork"))                {                    return ip[i].ToString();                }            }            return null;        }    }}
0 0
原创粉丝点击