




已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C# 网络编程系列专题六:UDP编程(转载: /zhili/archive/2012/08/23/WebServer.html )引用:前一个专题简单介绍了TCP编程的一些知识,UDP与TCP地位相当的另一个传输层协议,它也是当下流行的很多主流网络应用(例如QQ、MSN和Skype等一些即时通信软件传输层都是应用UDP协议的)底层的传输基础,所以在本专题中就简单介绍下UDP的工作原理和UDP编程的只是,希望可以对刚接触网络编程的朋友起到入门的作用。一、UDP介绍 UDP和TCP都是构建在IP层之上传输层的协议,但UDP是一种简单、面向数据报(Sock_Dgram)的无连接协议,提供的是不一定可靠的传输服务。然而TCP是一种面向连接、可靠的,面向字节流(Sock_Stream)的传输协议,对于“无连接”是指在正式通信前不必与对方先建立连接,不管对方状态如何都可以直接发送过去(就如QQ中通过QQ号查看好友后发送添加好友请求,此间不需要考虑对方的状态如何,都照样发送请求)。从UDP和TCP的定义中就可以看出它们两者的区别了,(1)UDP的可靠性不如TCP,因为TCP传输前要首先建立连接,这样就增加了TCP传输的可靠性,所以UDP也被称为不可靠的传输协议,关于TCP的介绍可以看我上一篇博客的介绍。 TCP和UDP还有另外一个区别。(2)UDP不能保证有序传输。即UDP不能确保数据的发送和接收顺序。下面就来看看UDP协议的工作原理,对UDP的工作原理有一个好的理解,对后面介绍的UDP编程也是一个好的基础。1.1 UDP的工作原理 UDP将网络数据流量压缩成数据报的形式,每一个数据报用8个字节(8 X 8位=64位)描述报头信息,剩余字节包含具体的传输数据。UDP报头(只有8个字节)相当于TCP的报头(至少20个字节)很短,UDP报头由4个域组成,每个域各占2个字节,具体为源端口、目的端口、用户数据报长度和校验和,具体结构见下图(下面也贴出了TCP报文的结构图,与UDP数据报做一个对比的作用): UDP协议和TCP协议都使用端口号为不同的应用保留其各自的数据传输通道这一机制,数据发送方将UDP数据报通过源端口发送出去,而数据接收方则通过目标端口接收数据。1.2 UDP的优势 前面介绍中说UDP相对于TCP是不可靠的,不能保证有序传输的传输协议,然而UDP协议相对于TCP协议的优势在哪里呢?,UDP相对于TCP的优势主要有三个方面的: (1)UDP速度比TCP快。 由于UDP不需要先与对方建立连接,也不需要传输确认,因此其数据的传输速度比TCP快很多。对于一些着重传输性能而不是传输完整性的应用(网络音频播放、视频点播和网络会议等),使用UDP协议更加适合,因为它传输速度快,使通过网络播放的视频音质好、画面清晰。 (2)UDP有消息边界。 通过UDP协议进行传输的发送方对应用程序交下来的报文,在添加首部后就向下直接交付给IP层。既不拆分也不合并,而是保留这些报文的边界,所以使用UDP协议不需要像TCP那样考虑消息边界的问题,这样就使得UDP编程相对于TCP在接收到的数据处理方面要简单的多。(对于TCP消息边界的问题可以查看相关的文档,在这里我就不列出来了) (3)UDP可以一对多传输 由于传输数据部建立连接,也就不需要维护连接状态,因此一台服务器可以同时向多个客户端发送相同的信息。利用UDP可以使用广播或者组播的方式同时向子网的所有客户端进程发送信息,广播和组播的介绍放到后面TCP编程中介绍。 上面介绍了UDP协议相对于TCP协议的优势,其中速度快是UDP的最重要的优势,也是像一些网络会议、即时通信软件传输层选择UDP协议进行传输的原因所在。 二、.net平台对UDP编程的支持 介绍完UDP相对于TCP的优势后,当然很希望在.net平台下开发一个基于UDP协议的一个应用了,然后.net平台下对UDP编程也做了很好的支持,为我们开发基于UDP协议的网络应用提供很多方便之处,下面就简单介绍.net平台下对UDP编程的支持(主要介绍提供的类来对UDP协议进行编程)。 .net类库中的UdpClient类对基础的Socket进行了封装,这样就在发送和接受数据时不需要考虑底层套接字的收发时处理的一些细节问题,这样为UDP编程提供了方便,也可以提高开发效率(感觉net就是做这样的事情的,对一些底层的实现进行封装,方便我们的调用,这也体现了面向对象语言的封装特性)对于这个的具体的使用我就不做过多的介绍的,在后面的UDP编程的实现部分将会对该类中主要方法的使用,大家可以查看MSDN来查看该类中其他成员的使用: /zh-cn/library/ System .Net.Sockets.UdpClient.aspx三、UDP编程的具体实现 由于UDP进程在通信之前是不需要建立连接,消息接收方可能并不知道是谁给它发的消息,因此UDP编程分为两种模式:一种“实名发送”,即接收方可以由收到的消息得知发送方进程端口,另外一种则为“匿名发送”,即接收方并不知道发给它信息的远程进程究竟来自哪个端口。下面通过一个winform 程序来演示下UDP的编程:实现代码:using System;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using System.Windows.Forms;namespace UDPClient public partial class frmUdp : Form private UdpClient sendUdpClient; private UdpClient receiveUpdClient; public frmUdp() InitializeComponent(); IPAddress ips = Dns.GetHostAddresses(); tbxlocalip.Text = ips3.ToString(); int port = 51883; tbxlocalPort.Text = port.ToString(); tbxSendtoIp.Text = ips3.ToString(); tbxSendtoport.Text = port.ToString(); / 接受消息 private void btnReceive_Click(object sender, EventArgs e) / 创建接收套接字 IPAddress localIp = IPAddress.Parse(tbxlocalip.Text); IPEndPoint localIpEndPoint = new IPEndPoint(localIp, int.Parse(tbxlocalPort.Text); receiveUpdClient = new UdpClient(localIpEndPoint); Thread receiveThread = new Thread(ReceiveMessage); receiveThread.Start(); / 接收消息方法 private void ReceiveMessage() IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); while (true) try / 关闭receiveUdpClient时此时会产生异常 byte receiveBytes = receiveUpdClient.Receive(ref remoteIpEndPoint); string message = Encoding.Unicode.GetString(receiveBytes); / 显示消息内容 ShowMessageforView(lstbxMessageView, string.Format(01, remoteIpEndPoint, message); catch break; / 利用委托回调机制实现界面上消息内容显示 delegate void ShowMessageforViewCallBack(ListBox listbox, string text); private void ShowMessageforView(ListBox listbox, string text) if (listbox.InvokeRequired) ShowMessageforViewCallBack showMessageforViewCallback = ShowMessageforView; listbox.Invoke(showMessageforViewCallback, new object listbox, text ); else lstbxMessageView.Items.Add(text); lstbxMessageView.SelectedIndex = lstbxMessageView.Items.Count - 1; lstbxMessageView.ClearSelected(); private void btnSend_Click(object sender, EventArgs e) if (tbxMessageSend.Text = string.Empty) MessageBox.Show(发送内容不能为空,提示); return; / 选择发送模式 if (chkbxAnonymous.Checked = true) / 匿名模式(套接字绑定的端口由系统随机分配) sendUdpClient = new UdpClient(0); else / 实名模式(套接字绑定到本地指定的端口) IPAddress localIp = IPAddress.Parse(tbxlocalip.Text); IPEndPoint localIpEndPoint = new IPEndPoint(localIp, int.Parse(tbxlocalPort.Text); sendUdpClient = new UdpClient(localIpEndPoint); Thread sendThread = new Thread(SendMessage); sendThread.Start(tbxMessageSend.Text); / 发送消息方法 private void SendMessage(object obj) string message = (string)obj; byte sendbytes = Encoding.Unicode.GetBytes(message); IPAddress remoteIp = IPAddress.Parse(tbxSendtoIp.Text); IPEndPoint remoteIpEndPoint = new IPEndPoint(remoteIp, int.Parse(tbxSendtoport.Text); sendUdpClient.Send(sendbytes, sendbytes.Length, remoteIpEndPoint); sendUdpClient.Close(); / 清空发送消息框 ResetMessageText(tbxMessageSend); / 采用了回调机制 / 使用委托实现跨线程界面的操作方式 delegate void ResetMessageCallback(TextBox textbox); private void ResetMessageText(TextBox textbox) / Control.InvokeRequired属性代表 / 如果控件的处理与调用线程在不同线程上创建的,则为true,否则为false if (textbox.InvokeRequired) ResetMessageCallback resetMessagecallback = ResetMessageText; textbox.Invoke(resetMessagecallback, new object textbox ); else textbox.Clear(); textbox.Focus(); / 停止接收 private void btnStop_Click(object sender, EventArgs e) receiveUpdClient.Close(); / 清空接受消息框 private void btnClear_Click(object sender, EventArgs e) this.lstbxMessageView.Items.Clear(); 运行结果: 实名发送: 在本地运行本程序的三个进程(分别为A,B,C),把进程C做为接受进程,进程A和进程B都向进程C发信息,进程A和进程分别绑定端口号为11883和21883,发送到端口都为51883,配置界面如下: 首先不勾选“匿名”复选框,在进程C中点击“接收”按钮开启接受线程,在A进程和B进程中发送消息框里分别输入你好,我是1和你好,我是2 ,然后点击发送按钮,此时在进程中就可以看到进程A和进程B发来的消息,如下图:从图中可以看出每条消息之前都显示了消息的准确来源(包括消息进程锁在的Ip地址和端口号)匿名发送: 下面把“匿名”复选框勾上后,再按照前面的步骤将得到下面的结果: 从图中结果可以看出此时列表中显示的消息来源的进程端口号分别为49439和49440,而不是发送消息进程的真实端口(11883和21883)。 这种UDP只能辨别消息源主机的Ip地址,而无法知道发消息的进程究竟是哪个端口称为“匿名发送”。正如我们平时发手机短信一样,如果我们把认识的名字和电话号码预先存在通讯录里,当一发来信息,接受方马上就可以从来电显示中看到是谁发来的(实名模式);但是如果是陌生人发来信息或者广告等信息时,仅看来电显示,根本不知道对方是谁(匿名模式),QQ发消息也是一样的道理。 四、UDP广播和组播前面UDP的实现中发送数据使用的都是一对一(单播)的通信方式,即只将数据发送到某一个进程。前面提到UDP可以实现一对多的传输方式,即通过广播和组播把数据发送给一组进程。下面就介绍下UDP广播和组播的相关知识。4.1 广播和组播的基本概念 虽然利用TCP协议可以保证数据的可靠、有序的传输,但是TCP仅支持一对以的传输,而且传输时需要在发送端和每一个接受端之间建立单独的数据通信通道,如果需要实现网络会议、网络视频的点播等功能时要向大量主机发送相同的数据包,如果采用单播方式逐个节点传输的话,将会给发送方带来网络堵塞等问题,此时可以考虑实现UDP的多播方式即广播和组播来实现这样的功能(一对多通信分为广播和组播两种形式)。 广播是指同时向子网中的多台计算机发送消息,并且所有子网中的计算机都可以接收到发送方发来的消息,每个广播消息包含一个特殊的IP地址,这个IP的中子网内主机标志部分的二进制都为1,例如,子网掩码为,对于子网192.168.0,则这个IP地址为55. 然后广播消息又分为本地广播和全球广播两种类型, 本地广播是指向子网中的所有计算机发送广播消息,其他网络不会受到本地广播的影响。 IP地址分为两部分网络标志部分和主机标志部分,这两部分是靠子网掩码来区分的,主机标记部分二进制全部为1的地址成为本地广播地址。例如:A类网络,使用子网掩码,则本地广播地址为: 对于IPv4来说,全球广播使用所有位全为1的IP地址,即55,这个广播地址代表数据报的目的地是网络上所有设备,但是由于路由器会自动过滤全球广播,所以使用这个地址根本就没有任何意义。 然后,当接收者分布于多个不同的子网时,广播将不再适用,此时可以通过组播的方式来实现,组播也叫多路广播,组播是将信息从一台计算机发送到本网或全网内指定的计算机上,即发送到那些加入了指定组播组的计算机上,每台计算机都可以通过程序随时加入某个组播组中,也可以随时退出来, 就像我们开网了会议一样,可以随时加入会议室进行开会,会议结束和会议进行中都可以随意的退出来。 4.2 加入和退出组播组 组播组又称为多路广播组,组播地址的范围在到55的D类IP地址(至于这个概念大家可以百度百科里面就查看)。任何发送到组播地址的消息都会被发送到组内所有成员设备上,组可以使永久的也可以是临时,大
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025至2030中国玉米甜味剂行业发展趋势分析与未来投资战略咨询研究报告
- 助力新人活动方案
- 全新活动策划方案
- 公司聚餐后娱乐活动方案
- 公司棋类比赛策划方案
- 公司组织火锅店活动方案
- 公司福利充值活动方案
- 公司整年活动策划方案
- 公司春节营销策划方案
- 公司端午员工活动方案
- 2023年黑龙江省文化和旅游系统事业单位人员招聘笔试模拟试题及答案解析
- 2023年江西新余市数字产业投资发展有限公司招聘笔试题库含答案解析
- LY/T 3323-2022草原生态修复技术规程
- 部编版六年级语文下册课件第1课《北京的春节》《腊八粥》
- 涂装工模拟练习题含答案
- 2023-2024学年河南省永城市小学数学二年级下册期末评估测试题
- 乳腺疾病的超声诊断 (超声科)
- 服务精神:马里奥特之路
- 《建筑施工安全检查标准》JGJ59-2011图解
- 华为大学人才培养与发展实践
- 医疗垃圾废物处理课件
评论
0/150
提交评论