域名频道-专业提供域名注册,网站空间,电子邮箱,VPS主机等服务
首页 域名注册 虚拟主机 香港主机 美国主机 VPS主机 网站建设 ShopEX网店 软件开发 客户中心 购物车
域名服务,域名注册 常见问题
文章搜索


本类TOP10
·松江网页设计_松江网页制...
·上海轨道交通图-上海地图
·松江公交线路图-松江地图
·marquee连续滚动
·今天几度?-天气预报-全...
·松江新城地图-松江地图
·松江城区地图-松江地图
·HAO123邮箱登陆代码
·shopex免费模板,下...
·松江DNS服务器地址,松...
当前位置:域名频道首页 > 常见问题 > 网页制作
全面掌握VisualC#实现UDP协议(一)

UDP(User Datagram Prot ocol)协议就是“用户数据报协议”,它是一种无连接的协议, 无连接主要是和TCP协议相比较的。我们知道当利用TCP协议传 送数据的时候,首先必须先建立连接(也就是所谓的握手)才可以传 输数据。而当计算机利用UDP协议进行数据传输的时候,发送方只 需要知道对方的IP地址和端口号就可以发送数据,而并不需要进行 连接。当然如果你非要进行连接,通过Visual C#也是可以 实现的,但前提是要确定连接的远程主机的端口号处于监听状态,否 则程序会出现不必要的错误,但这是种画蛇添足的做法,不仅丢失了 UDP协议的无连接传送数据的特点和优点,而且还给程序运行带来 了不安定的因素。所以这种方法并不值得提倡。
由于UDP 协议并不需要进行确定的连接,所以编写基于UDP协议的应用程序 比起编写基于TCP协议的应用程序要简单些(程序中可以不需要考 虑连接和一些异常的捕获工作)。但同时也给基于UDP协议编写的 程序带来了一个致命的缺点,UDP由于不提供可靠数据的传输,当 计算机之间利用UDP协议传送数据的时候,发送方只管发送数据, 而并不确认数据是否被对方接收。这样就会导致某些UDP协议数据 包在传送的过程中丢失,尤其网络质量不令人满意的情况下,丢失数 据包的现象会更严重。这就是为什么在网络上传输重要数据不采用U DP协议的原因。
但是我们也不能因为这一个缺点就全面否 定UDP协议,这是因为虽然利用UDP协议来传送安全性要求高的 数据是不适合的,但对于那些不重要的数据,或者即使丢失若干数据 包也不影响整体性的数据,如音频数据,视频数据等,采用UDP协 议就是一个非常不错的选择。如目前网络流行的很多即时聊天程序, 如OICQ和ICQ等,采用的就是UDP协议。同时虽然UDP协 议无法保证数据可靠性,但具有对网络资源开销较小,数据处理速度 快的优点,所以在有些对数据安全性要求不是很高的情况下,采用U DP协议也是一个非常不错的选择。
总结一下上面的内容, 可见UDP是一种不面向连接的网络协议,既有其优点,也有其不足 ,具体如下:
1.基于UDP协议的网络应用程序,实现起 来比较简单,并且基于UDP协议的网络应用程序在运行时,由于受 到环境影响较小,所以不容易出错。
2.UDP协议占用网 络资源较少,数据处理较快,所以在网络中传送对安全性要求不是十 分高数据时,其优点比较明显。所谓对安全性要求不高的数据,是指 那些不重要的数据,或者是即使丢失若干数据,也不影响其整体的数 据,如音频数据等。目前很多流行的网络应用程序都是基于UDP协 议的,如OICQ、ICQ等。
3.由于其不是面向连接的 网络协议,其缺点也是非常明显的,有些时候甚至是致命的。因为使 用UDP协议来传送数据,在数据发送后,在发送方并不确认对方是 否接收到。这样就可能导致传送的数据在网络中丢失,尤其在网络条 件并不很好的情况下,丢失数据包的现象就更多。所以传送重要数据 一般不采用UDP协议。
二.简介Visual C#发送 、接收UDP数据包使用的主要类及其用法:
用Visua l C#实现UDP协议,最为常用,也是最为关键的类就是Udp Client,UdpClient位于命名空间System.N et.Sockets中,Visual C#发送、接收UDP数 据包都是通过UdpClient类的。表01和表02是UdpC lient类中常用方法和属性及其简要说明。

< br>
方法
说明


Close
关闭 UDP 连接


Connect
建立与远程主机的连接

DropMulticastGroup
退出多路广播组


JoinMultic astGroup
将 UdpClient 添加到多路 广播组


Receive
返回 已由远程主机发送的 UDP 数据文报


Send
将 UDP 数据文报发送到远程主机

 

表01:UdpClient类中常用 方法及其说明。

 

属性
说明


Active
获取或 设置一个值,该值指示是否已建立了与远程主机的连接

Client
获取或设置基础网络套接字


表02:UdpClient类中常用方 法及其说明。
1.Visual C#使用UdpClie nt类发送UDP数据包:
在具体使用中,一般分成二种情 况:
(1). 知道远程计算机IP地址:
"Se nd"方法的调用语法如下:

 


public int Send ( byte[] dgram ,
int bytes ,
IPEndPoint endPo int
) ;

 

< br>
参数说明:
dgram 要发送的 UDP 数据文报(以字节数组表示)。
bytes 数据文报中的字节数。
endPoint 一个 IPEndPoint,它表示要将数据文报发送到的主机和端口 。
返回值 已发送的字节数。
下面使用Udp Client发送UDP数据包的具体的调用例子:

 


IPAddress HostIP = new IPAddress.Parse ( "
远程计算机IP地址"
) ;
< br>IPEndPoint host = new IPEnd Point ( HostIP , 8080 ) ;

U dpClient.Send ( "
发送的字节&qu ot;
, "
发送的字节长度"
, ho st ) ;

 


(2). 知道远程计算机名称::
知道远程计算机名 称后,利用"Send"方法直接把UDP数据包发送到远程主机的 指定端口号上了,这种调用方式也是最容易的,语法如下:

 


public int Send (
byte[ ] dgra m ,
int bytes ,
st ring hostname ,
int port
) ;

 


< br>参数说明:
dgram 要发送的 UD P 数据文报(以字节数组表示)。
bytes 数据文报中的字节数。
hostname 要连接到的远程主机的名称。
port 要 与其通讯的远程端口号。
返回值 已发送的字节 数。
2.Visual C#使用UdpClient类接 收UDP数据包:
接收UDP数据包使用的是UdpCli ent中的“Receive”方法。此方法的调用语法如下:

 

publ ic byte [] Receive (
ref IPEndPoint remoteEP
) ;

 


参数
r emoteEP 是一个 IPEndPoint类的实例 ,它表示网络中发送此数据包的节点。
如果指定了远程计算 机要发送到本地机的端口号,也可以通过侦听本地端口号来实现对数 据的获取,下面就是通过侦听本地端口号“8080”来获取信息代 码:

 


server = new UdpClient ( ) ;
receivePoint = new IPEndPoin t
(new IPAddress ( "
1 27.0.0.1"
) , 8080 ) ;

byte[] recData = server.Recei ve ( ref receivePoint ) ;

 

 

三.Visual C#实现UDP协议之网络对时系统的体系结构及功能简介:
在局域网中有很多应用软件为了协同工作,需要保证客户机上时间 统一,而为了实现这一点,通常的做法是客户机从一个时间相对正确 的服务器读取时间,以此来校正本地时间。如经常看到的GPS对时 系统等。本节编写的局域网上对时系统的主要的功能是保证局域网上 计算机时间、日期的统一。网络对时程序是体系结构分成服务器端程 序和客户端程序二个部分,具体的作法是:在同一个网段上,固定一 台计算机作为对时的服务器,在这个网段的所有计算机都可以读取这 台服务器上的时间和日期,并依此服务器上的时间和日期为基准,来 确定本地的时间和日期。在服务器端程序需要达到以下功能:
能够接收局域网中任一台客户机的请求
记录请求客户机的 计算机名称,和请求时间
准确发送服务器端的时间和日期< br>端程序要达到以下功能:
能够设定服务器的主机或者 IP地址
能够接收服务器端发送的时间、日期信息
能够以接收的服务器端时间、日期为基准,校正本地时间
因 此在具体用Visual C#实现网络对时系统时就包括二个部分 :服务器端程序和客户端程序。下面首先介绍Visual C#实 现网络对时系统中服务器端程序的具体步骤。
四.Visu al C#实现网络对时系统之服务器端程序的具体步骤:
服务器端程序比客户端程序相对要简单,主要因是服务器端程序的工 作比较简单,就
是接收客户端的对时请求、发送服务器端的 时间数据。而于客户端不仅要传送和接收数据,还要把服务器端的时 间提取出来,并以此来修改本地计算机的时间、日期。下面是用Vi sual C#实现网络对时系统之服务器端程序的具体步骤步骤。
1.启动Visual Studio .Net。
2.选择菜单【文件】|【新建】|【项目】后,弹出【新建项目 】对话框。
3.将【项目类型】设置为【Visual C #项目】。
4.将【模板】设置为【Windows应用程 序】。
5.在【名称】文本框中输入【UDP对时服务器端 】。
6.在【位置】的文本框中输入【E:\VS.NET 项目】,然后单击【确定】按钮
7.在【解决方案资源管理 器】窗口中,双击Form1.cs文件,进入Form1.cs文 件的编辑界面。
8.在Form1.cs文件的开头,用下 列导入命名空间代码替代系统缺省的导入命名空间代码。
< br>


using S ystem ;

using System.Drawin g ;

using System.Collection s ;

using System.ComponentM odel ;

using System.Windows .Forms ;

using System.Data ;

using System.Net ;

usi ng System.Net.Sockets ;

usi ng System.Threading ;

//程序中 使用到线程
using System.Text ;
//程序中使用到编码

 


9.切换到【Form1.cs(设计)】窗口, 并从【工具箱】中的【Windows窗体组件】中往窗体中拖入下 列组件,并执行相应操作:
一个Label组件,显示对时 服务器正在运行信息
一个ListBox组件,名称为li stBox1,用以显示客户端和服务器端交流的日志
一个 Button组件,名称为button1,并在其拖入窗体后,双 击,则系统会在Form1.cs文件中产生其Click事件对应 的处理代码。
10.在【解决方案资源管理器】窗口中,双 击Form1.cs文件,进入Form1.cs文件的编辑界面。 在Form1.cs中的class代码区添加下列代码,下列代码 是定义程序中使用的全局变量和创建全局使用的实例:

 

private UdpClient server ;

private IPEndPoint receivePoint ;

p rivate int port = 8080 ;

/ /定义端口号
private int ip = 127 001 ;

//设定本地IP地址
private Thread startServer ;

< br>


11.以下面代码替代系统产 生的InitializeComponent过程。

 

private void InitializeComponent ( ){
this.listBox1 = new Sys tem.Windows.Forms.ListBox ( ) ;

this.label1 = new System. Windows.Forms.Label ( ) ;

t his.button1 = new System.Windo ws.Forms.Button ( ) ;

this. SuspendLayout ( ) ;

this.li stBox1.ItemHeight = 12 ;

th is.listBox1.Location = new Sys tem.Drawing.Point ( 14 , 40 ) ;

this.listBox1.Name = &quo t;
listBox1"
;

this.lis tBox1.Size = new System.Drawin g.Size ( 268 , 220 ) ;

this .listBox1.TabIndex = 0 ;

th is.label1.ForeColor = System.D rawing.Color.Red ;

this.lab el1.Location = new System.Draw ing.Point ( 44 , 10 ) ;

thi s.label1.Name = "
label1&q uot;
;

this.label1.Size = n ew System.Drawing.Size ( 210 , 24 ) ;

this.label1.TabInde x = 1 ;

this.label1.Text = "
UDP对时服务器端正在运行......" ;
;

this.button1.FlatStyle = System.Windows.Forms.FlatSty le.Flat ;

this.button1.Loca tion = new System.Drawing.Poin t ( 106 , 278 ) ;

his.butto n1.Name = "
button1"
;

this.button1.Size = new S ystem.Drawing.Size ( 75 , 34 ) ;

this.button1.TabIndex = 2 ;

this.button1.Text = &qu ot;
清除信息"
;

this.button 1.Click += new System.EventHan dler ( this.button1_Click ) ;
< br>this.AutoScaleBaseSize = ne w System.Drawing.Size ( 6 , 14 ) ;

this.ClientSize = new System.Drawing.Size ( 300 , 32 9 ) ;

this.Controls.AddRang e ( new System.Windows.Forms.C ontrol[] {
this.button1 ,
this.listBox1 ,
this.label1} ) ;

this.Maxim izeBox = false ;

this.Name = "
Form1"
;

this. Text = "
UDP对时服务器端"
;

this.Load += new System.Ev entHandler ( this.Form1_Load ) ;

this.ResumeLayout ( fals e ) ;

}

 

至此,【UDP对时服务器端】项目的界面设计和功能 实现的前期工作就完成了,设计界面如图01所示:

图01:【UDP对时服务器端】项目的设计界面12.在Form1.cs文件中的InitializeCo mponent过程的后面添加下面代码,下列代码是定义过程“s tart_server”。此过程的功能是获取客户端对时请求数 据,并向客户端发送服务器当前时间和日期。

 

public void start_server ( )
{
while ( true )
{
//接收从远程主机发送 到本地8080端口的数据
byte[] recDat a = server.Receive ( ref recei vePoint ) ;

ASCIIEncoding encode = new ASCIIEncoding ( ) ;

//获得客户端请求数据
string Read_str = encode.GetString ( recData ) ;

//提取客户端的信息,存放到 定义为temp的字符串数组中
string[] te mp = Read_str.Split ( "
/& quot;
.ToCharArray ( ) ) ;

//显示端口号的请求信息
listBox1.Item s.Add ( "
时间:"
+ DateT ime.Now.
ToLongTim eString ( ) + "
接收信息如下: "
) ;

listBox1.Items. Add ( "
客户机:"
+ temp[ 0] ) ;

listBox1.Items.Add ( "
端口号:"
+ temp[1] ) ;

//发送服务器端时间和日期
byte[ ] sendData =encode.GetBytes ( System.DateTime.N ow.ToString ( ) ) ;

listBo x1.Items.Add ( "
发送服务器时间!& quot;
) ;

//对远程主机的指定端口号发送服 务器时间
server.Send ( sendDat a , sendData.Length ,
temp[0] , Int32.Parse ( t emp[1] ) ) ;

}
}

 


请注意:上述代码中约定客 户机程序发送对时请求信息到服务器的8080端口号。服务器端程 序接收发送到本地8080端口号的数据就完成了数据接收。为了能 够让服务器端程序知道是那台客户机提出请求和要把对时信息发送到 客户机的那个端口号上,客户端程序对发送的对时请求信息进行了设 计。客户端的对时请求信息结构为:
计算机名称 + / + 客户机接收信息端口号
这样如果客户端计算机名称 为:majinhu,接收服务器端时间数据的端口号是8080, 则客户端程序发送的对时请求数据就为:majinhu/8080 。
服务器端程序在接收到客户端对时请求数据,并进行分析 后,就能够通过UdpClient类的Send方法准确的把服务 器端当前的时间和日期发送到客户端指定的端口号上。这样客户端程 序通过读取指定的端口号,就能够获得服务器端当前的时间和日期, 从而以此来修正客户端的时间和日期了。
13.在“sta rt_server”过程之后面添加下面代码,下列代码是定义“ run”过程。“run”过程的作用是创建一个线程实例,并以“ start_server”过程来初始化线程实例。之所以采用线 程是因为服务器端程序需要不间断读取发送到8080端口号,并且 Receive方法是一个阻塞式方法。采用线程就是为了保证服务 器端程序正常运行:

 

< br> public void run ( )
{
//利用本地8080端口号来初始化一个UDP网络服 务
server = new UdpClient ( port ) ;

receivePoint = new IPEndPoint ( new IPAddress ( ip ) , port ) ;

//开一个线程
startServer = new Thread ( new ThreadStart ( start_server ) ) ;

//启动线程
startServer.S tart ( ) ;

}

< br>

14.在Form1.cs中的Main函 数之后添加下列代码,下列代码是定义“Form1_Load”事 件,在此事件中将调用“run”过程,这样当服务器端程序运行后 ,就启动网络对时服务:

 


private void Form1_Lo ad ( object sender , System.Ev entArgs e )
{
//启动对时服务< br> run ( ) ;

}

 


15.在Form1.cs文件中的 “Form1_Load”事件之后,添加下列代码,下列代码是定 义button1的“Click”事件,此事件的作用是清除服务 器端程序显示的日志信息:

 


private void button1 _Click ( object sender , Syste m.EventArgs e )
{
//清除服 务器端程序日志
listBox1.Items.Cle ar ( ) ;

}

 


16.用下列代码替换Form1.cs中的D ispose方法。下列代码的功能是手动收集程序中使用的资源:

 


pr otected override void Dispose ( bool disposing )
{
try
{
//关闭线程
sta rtServer.Abort ( ) ;

//清除 资源
server.Close ( ) ;

}
catch
{
} ;

if ( disposing )
{
if ( components != null ) {
components.Dispose ( ) ;

}
}
base.D ispose ( disposing ) ;

}

 


至此,在上 述步骤都正确完成,【UDP对时服务器端】项目的全部工作就完成 了。图02【UDP对时服务器端】运行后的界面,在日志信息中记 录了对时请求客户机的名称,发送对时数据的端口号以及客户端请求 的时间:


图02:【UDP对时服务器 端】项目的运行界面

来自:域名频道 时间:2006-9-19 返回 常见问题 首页
关于我们 联系方式 付款事宜 招聘启事 网站地图 域名注册 虚拟主机 法律顾问

Copyright 2000-2013 域名频道(www.DNS110.com)
地址:上海市松江区新松江路1188弄37号 邮编:201620
电话:021-67820741 67820742 67820743 传真:转分机805 值班电话:021-67820743
QQ:219854 Email:support@dns110.com