全面掌握VisualC#实现UDP协议.docx
- 文档编号:9280903
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:21
- 大小:89.67KB
全面掌握VisualC#实现UDP协议.docx
《全面掌握VisualC#实现UDP协议.docx》由会员分享,可在线阅读,更多相关《全面掌握VisualC#实现UDP协议.docx(21页珍藏版)》请在冰豆网上搜索。
全面掌握VisualC#实现UDP协议
全面掌握VisualC#实现UDP协议
一.走进UDP协议:
UDP(UserDatagramProtocol)协议就是“用户数据报协议”,它是一种无连接的协议,无连接主要是和TCP协议相比较的。
我们知道当利用TCP协议传送数据的时候,首先必须先建立连接(也就是所谓的握手)才可以传输数据。
而当计算机利用UDP协议进行数据传输的时候,发送方只需要知道对方的IP地址和端口号就可以发送数据,而并不需要进行连接。
当然如果你非要进行连接,通过VisualC#也是可以实现的,但前提是要确定连接的远程主机的端口号处于监听状态,否则程序会出现不必要的错误,但这是种画蛇添足的做法,不仅丢失了UDP协议的无连接传送数据的特点和优点,而且还给程序运行带来了不安定的因素。
所以这种方法并不值得提倡。
由于UDP协议并不需要进行确定的连接,所以编写基于UDP协议的应用程序比起编写基于TCP协议的应用程序要简单些(程序中可以不需要考虑连接和一些异常的捕获工作)。
但同时也给基于UDP协议编写的程序带来了一个致命的缺点,UDP由于不提供可靠数据的传输,当计算机之间利用UDP协议传送数据的时候,发送方只管发送数据,而并不确认数据是否被对方接收。
这样就会导致某些UDP协议数据包在传送的过程中丢失,尤其网络质量不令人满意的情况下,丢失数据包的现象会更严重。
这就是为什么在网络上传输重要数据不采用UDP协议的原因。
但是我们也不能因为这一个缺点就全面否定UDP协议,这是因为虽然利用UDP协议来传送安全性要求高的数据是不适合的,但对于那些不重要的数据,或者即使丢失若干数据包也不影响整体性的数据,如音频数据,视频数据等,采用UDP协议就是一个非常不错的选择。
如目前网络流行的很多即时聊天程序,如OICQ和ICQ等,采用的就是UDP协议。
同时虽然UDP协议无法保证数据可靠性,但具有对网络资源开销较小,数据处理速度快的优点,所以在有些对数据安全性要求不是很高的情况下,采用UDP协议也是一个非常不错的选择。
总结一下上面的内容,可见UDP是一种不面向连接的网络协议,既有其优点,也有其不足,具体如下:
1.基于UDP协议的网络应用程序,实现起来比较简单,并且基于UDP协议的网络应用程序在运行时,由于受到环境影响较小,所以不容易出错。
2.UDP协议占用网络资源较少,数据处理较快,所以在网络中传送对安全性要求不是十分高数据时,其优点比较明显。
所谓对安全性要求不高的数据,是指那些不重要的数据,或者是即使丢失若干数据,也不影响其整体的数据,如音频数据等。
目前很多流行的网络应用程序都是基于UDP协议的,如OICQ、ICQ等。
3.由于其不是面向连接的网络协议,其缺点也是非常明显的,有些时候甚至是致命的。
因为使用UDP协议来传送数据,在数据发送后,在发送方并不确认对方是否接收到。
这样就可能导致传送的数据在网络中丢失,尤其在网络条件并不很好的情况下,丢失数据包的现象就更多。
所以传送重要数据一般不采用UDP协议。
二.简介VisualC#发送、接收UDP数据包使用的主要类及其用法:
方法
说明
Close
关闭UDP连接
Connect
建立与远程主机的连接
DropMulticastGroup
退出多路广播组
JoinMulticastGroup
将UdpClient添加到多路广播组
Receive
返回已由远程主机发送的UDP数据文报
Send
将UDP数据文报发送到远程主机
表01:
UdpClient类中常用方法及其说明。
属性
说明
Active
获取或设置一个值,该值指示是否已建立了与远程主机的连接
Client
获取或设置基础网络套接字
表02:
UdpClient类中常用方法及其说明。
1.VisualC#使用UdpClient类发送UDP数据包:
在具体使用中,一般分成二种情况:
(1).知道远程计算机IP地址:
"Send"方法的调用语法如下:
publicintSend(byte[]dgram,intbytes,IPEndPointendPoint);
参数说明:
dgram要发送的UDP数据文报(以字节数组表示)。
bytes数据文报中的字节数。
endPoint一个IPEndPoint,它表示要将数据文报发送到的主机和端口。
返回值已发送的字节数。
下面使用UdpClient发送UDP数据包的具体的调用例子:
IPAddressHostIP=newIPAddress.Parse("远程计算机IP地址");IPEndPointhost=newIPEndPoint(HostIP,8080);UdpClient.Send("发送的字节","发送的字节长度",host);
(2).知道远程计算机名称:
:
知道远程计算机名称后,利用"Send"方法直接把UDP数据包发送到远程主机的指定端口号上了,这种调用方式也是最容易的,语法如下:
publicintSend(byte[]dgram,intbytes,stringhostname,intport);
参数说明:
dgram要发送的UDP数据文报(以字节数组表示)。
bytes数据文报中的字节数。
hostname要连接到的远程主机的名称。
port要与其通讯的远程端口号。
返回值已发送的字节数。
2.VisualC#使用UdpClient类接收UDP数据包:
接收UDP数据包使用的是UdpClient中的“Receive”方法。
此方法的调用语法如下:
publicbyte[]Receive(refIPEndPointremoteEP);
参数
remoteEP是一个IPEndPoint类的实例,它表示网络中发送此数据包的节点。
如果指定了远程计算机要发送到本地机的端口号,也可以通过侦听本地端口号来实现对数据的获取,下面就是通过侦听本地端口号“8080”来获取信息代码:
server=newUdpClient();receivePoint=newIPEndPoint(newIPAddress("127.0.0.1"),8080);byte[]recData=server.Receive(refreceivePoint);
三.VisualC#实现UDP协议之网络对时系统的体系结构及功能简介:
在局域网中有很多应用软件为了协同工作,需要保证客户机上时间统一,而为了实现这一点,通常的做法是客户机从一个时间相对正确的服务器读取时间,以此来校正本地时间。
如经常看到的GPS对时系统等。
本节编写的局域网上对时系统的主要的功能是保证局域网上计算机时间、日期的统一。
网络对时程序是体系结构分成服务器端程序和客户端程序二个部分,具体的作法是:
在同一个网段上,固定一台计算机作为对时的服务器,在这个网段的所有计算机都可以读取这台服务器上的时间和日期,并依此服务器上的时间和日期为基准,来确定本地的时间和日期。
在服务器端程序需要达到以下功能:
能够接收局域网中任一台客户机的请求
记录请求客户机的计算机名称,和请求时间
准确发送服务器端的时间和日期
端程序要达到以下功能:
能够设定服务器的主机或者IP地址
能够接收服务器端发送的时间、日期信息
能够以接收的服务器端时间、日期为基准,校正本地时间
因此在具体用VisualC#实现网络对时系统时就包括二个部分:
服务器端程序和客户端程序。
下面首先介绍VisualC#实现网络对时系统中服务器端程序的具体步骤。
四.VisualC#实现网络对时系统之服务器端程序的具体步骤:
usingSystem;usingSystem.Drawing;usingSystem.Collections;usingSystem.ComponentModel;usingSystem.Windows.Forms;usingSystem.Data;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Threading;//程序中使用到线程usingSystem.Text;//程序中使用到编码
9.切换到【Form1.cs(设计)】窗口,并从【工具箱】中的【Windows窗体组件】中往窗体中拖入下列组件,并执行相应操作:
一个Label组件,显示对时服务器正在运行信息
一个ListBox组件,名称为listBox1,用以显示客户端和服务器端交流的日志
一个Button组件,名称为button1,并在其拖入窗体后,双击,则系统会在Form1.cs文件中产生其Click事件对应的处理代码。
10.在【解决方案资源管理器】窗口中,双击Form1.cs文件,进入Form1.cs文件的编辑界面。
在Form1.cs中的class代码区添加下列代码,下列代码是定义程序中使用的全局变量和创建全局使用的实例:
privateUdpClientserver;privateIPEndPointreceivePoint;privateintport=8080;//定义端口号privateintip=127001;//设定本地IP地址privateThreadstartServer;
11.以下面代码替代系统产生的InitializeComponent过程。
privatevoidInitializeComponent(){this.listBox1=newSystem.Windows.Forms.ListBox();this.label1=newSystem.Windows.Forms.Label();this.button1=newSystem.Windows.Forms.Button();this.SuspendLayout();this.listBox1.ItemHeight=12;this.listBox1.Location=newSystem.Drawing.Point(14,40);this.listBox1.Name="listBox1";this.listBox1.Size=newSystem.Drawing.Size(268,220);this.listBox1.TabIndex=0;this.label1.ForeColor=System.Drawing.Color.Red;this.label1.Location=newSystem.Drawing.Point(44,10);this.label1.Name="label1";this.label1.Size=newSystem.Drawing.Size(210,24);this.label1.TabIndex=1;this.label1.Text="UDP对时服务器端正在运行......";this.button1.FlatStyle=System.Windows.Forms.FlatStyle.Flat;this.button1.Location=newSystem.Drawing.Point(106,278);his.button1.Name="button1";this.button1.Size=newSystem.Drawing.Size(75,34);this.button1.TabIndex=2;this.button1.Text="清除信息";this.button1.Click+=newSystem.EventHandler(this.button1_Click);this.AutoScaleBaseSize=newSystem.Drawing.Size(6,14);this.ClientSize=newSystem.Drawing.Size(300,329);this.Controls.AddRange(newSystem.Windows.Forms.Control[]{this.button1,this.listBox1,this.label1});this.MaximizeBox=false;this.Name="Form1";this.Text="UDP对时服务器端";this.Load+=newSystem.EventHandler(this.Form1_Load);this.ResumeLayout(false);}
至此,【UDP对时服务器端】项目的界面设计和功能实现的前期工作就完成了,设计界面如图01所示:
publicvoidstart_server(){while(true){//接收从远程主机发送到本地8080端口的数据byte[]recData=server.Receive(refreceivePoint);ASCIIEncodingencode=newASCIIEncoding();//获得客户端请求数据stringRead_str=encode.GetString(recData);//提取客户端的信息,存放到定义为temp的字符串数组中string[]temp=Read_str.Split("/".ToCharArray());//显示端口号的请求信息listBox1.Items.Add("时间:
"+DateTime.Now.ToLongTimeString()+"接收信息如下:
");listBox1.Items.Add("客户机:
"+temp[0]);listBox1.Items.Add("端口号:
"+temp[1]);//发送服务器端时间和日期byte[]sendData=encode.GetBytes(System.DateTime.Now.ToString());listBox1.Items.Add("发送服务器时间!
");//对远程主机的指定端口号发送服务器时间server.Send(sendData,sendData.Length,temp[0],Int32.Parse(temp[1]));}}
请注意:
上述代码中约定客户机程序发送对时请求信息到服务器的8080端口号。
服务器端程序接收发送到本地8080端口号的数据就完成了数据接收。
为了能够让服务器端程序知道是那台客户机提出请求和要把对时信息发送到客户机的那个端口号上,客户端程序对发送的对时请求信息进行了设计。
客户端的对时请求信息结构为:
计算机名称+/+客户机接收信息端口号
这样如果客户端计算机名称为:
majinhu,接收服务器端时间数据的端口号是8080,则客户端程序发送的对时请求数据就为:
majinhu/8080。
服务器端程序在接收到客户端对时请求数据,并进行分析后,就能够通过UdpClient类的Send方法准确的把服务器端当前的时间和日期发送到客户端指定的端口号上。
这样客户端程序通过读取指定的端口号,就能够获得服务器端当前的时间和日期,从而以此来修正客户端的时间和日期了。
13.在“start_server”过程之后面添加下面代码,下列代码是定义“run”过程。
“run”过程的作用是创建一个线程实例,并以“start_server”过程来初始化线程实例。
之所以采用线程是因为服务器端程序需要不间断读取发送到8080端口号,并且Receive方法是一个阻塞式方法。
采用线程就是为了保证服务器端程序正常运行:
publicvoidrun(){//利用本地8080端口号来初始化一个UDP网络服务server=newUdpClient(port);receivePoint=newIPEndPoint(newIPAddress(ip),port);//开一个线程startServer=newThread(newThreadStart(start_server));//启动线程startServer.Start();}
privatevoidForm1_Load(objectsender,System.EventArgse){//启动对时服务run();}
privatevoidbutton1_Click(objectsender,System.EventArgse){//清除服务器端程序日志listBox1.Items.Clear();}
protectedoverridevoidDispose(booldisposing){try{//关闭线程startServer.Abort();//清除资源server.Close();}catch{};if(disposing){if(components!
=null){components.Dispose();}}base.Dispose(disposing);}
至此,在上述步骤都正确完成,【UDP对时服务器端】项目的全部工作就完成了。
图02【UDP对时服务器端】运行后的界面,在日志信息中记录了对时请求客户机的名称,发送对时数据的端口号以及客户端请求的时间:
图02:
【UDP对时服务器端】项目的运行界面
五.VisualC#实现网络对时系统之客户端程序的具体步骤:
客户端的程序比服务器端程序要复杂些,因为客户端程序不仅要往服务器端发送对时请求信息,接收服务器端反馈的日期和时间数据,还要提取这些时间和日期信息,并以此来修改本地端的日期和时间。
参照上面实现网络对时系统服务器端程序,实现请求信息的发送和接收应相对要容易许多。
所以客户端程序的关键就是根据获得的服务器端日期、时间数据来修改本地的日期、时间。
在.NetFrameWorkSDK3705版本中并没有提供修改本地日期和时间的函数和类库,本文的实现办法是引入WinAPI函数,通过对应的WinAPI函数来更正本地时间和日期的,具体可参阅以下第十三和第十八步。
以下是VisualC#实现网络对时系统之客户端程序的具体实现步骤:
1.启动VisualStudio.Net。
2.选择菜单【文件】|【新建】|【项目】后,弹出【新建项目】对话框。
3.将【项目类型】设置为【VisualC#项目】。
4.将【模板】设置为【Windows应用程序】。
5.在【名称】文本框中输入【UDP对时客户端】。
6.在【位置】的文本框中输入【E:
\VS.NET项目】,然后单击【确定】按钮。
7.【解决方案资源管理器】窗口中,双击Form1.cs文件,进入Form1.cs文件的编辑界面。
8.在Form1.cs文件的开头,用下列导入命名空间代码替换Form1.cs中缺省的导入命名空间代码。
usingSystem.Collections;
usingSystem.ComponentModel;
usingSystem.Windows.Forms;
usingSystem.Data;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Runtime.InteropServices;
//程序引入WinAPI函数要使用到
9.把VisualStudio.Net的集成开发环境的当前窗口切换到【Form1.cs(设计)】窗体设计界面,并从【工具箱】中的【Windows窗体组件】中往窗体中拖入下列组件,并执行相应操作:
三个TextBox组件,分别用来输入服务器的IP地址,和显示本地时间、服务器的时间
二个Button组件,分别是button1和button2,在设计界面中分别双击button1和button2,系统会自动产生它们对应的Click事件处理代码。
三干个Label组件。
10.【解决方案资源管理器】窗口中,双击Form1.cs文件,进入Form1.cs文件的编辑界面。
在Form1.cs中的namespace代码区添加下列代码,下列代码的功能是在程序中定义系统时间的结构体。
[StructLayout(LayoutKind.Sequential)]
publicclassSystemTime
{
publicshortyear;
publicshortMonth;
publicshortDayOfWeek;
publicshortDay;
publicshortHour;
publicshortMinute;
publicshortSecond;
publicshortMilliseconds;
}
//定义系统时间的结构
privateUdpClientclient;
//创建UDP网络服务
privateIPEndPointreceivePoint;
privateintport=8080;
//定义接收服务器端程序发送对时信息对应的端口号
privatestringtimeString=DateTime.Now.ToString();
//存放时间日期信息字符串
privateDateTimetemp;
//定义一个时间类型,用以修改当前时间和日期
privatevoidInitializeComponent()
{
this.button1=newSystem.Windows.Forms.Button();
this.button2=newSystem.Windows.Forms.Button();
this.textBox1=newSystem.Windows.Forms.TextBox();
this.textBox2=newSystem.Windows
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 全面 掌握 VisualC 实现 UDP 协议
![提示](https://static.bdocx.com/images/bang_tan.gif)