12.并以下面代码替换Form.cs中由系统产生的InitializeComponent过程。
PRivate void InitializeComponent ( )
{
this.button1 = new System.Windows.Forms.Button ( ) ;
this.button2 = new System.Windows.Forms.Button ( ) ;
this.textBox1 = new System.Windows.Forms.TextBox ( ) ;
this.textBox2 = new System.Windows.Forms.TextBox ( ) ;
this.label1 = new System.Windows.Forms.Label ( ) ;
this.label2 = new System.Windows.Forms.Label ( ) ;
this.label3 = new System.Windows.Forms.Label ( ) ;
this.textBox3 = new System.Windows.Forms.TextBox ( ) ;
this.SuspendLayout ( ) ;
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat ;
this.button1.Location = new System.Drawing.Point ( 128 , 128 ) ;
this.button1.Name = "button1" ;
this.button1.Size = new System.Drawing.Size ( 112 , 40 ) ;
this.button1.TabIndex = 0 ;
this.button1.Text = "获取" ;
this.button1.Click += new System.EventHandler ( this.button1_Click ) ;
this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat ;
this.button2.Location = new System.Drawing.Point ( 128 , 184 ) ;
this.button2.Name = "button2" ;
this.button2.Size = new System.Drawing.Size ( 112 , 40 ) ;
this.button2.TabIndex = 1 ;
this.button2.Text = "对时" ;
this.button2.Click += new System.EventHandler ( this.button2_Click ) ;
this.textBox1.Location = new System.Drawing.Point ( 120 , 56 ) ;
this.textBox1.Name = "textBox1" ;
this.textBox1.Size = new System.Drawing.Size ( 200 , 21 ) ;
this.textBox1.TabIndex = 2 ;
this.textBox1.Text = "" ;
this.textBox2.Location = new System.Drawing.Point ( 120 , 88 ) ;
this.textBox2.Name = "textBox2" ;
this.textBox2.Size = new System.Drawing.Size ( 200 , 21 ) ;
this.textBox2.TabIndex = 3 ;
this.textBox2.Text = "" ;
this.label1.Location = new System.Drawing.Point ( 48 , 56 ) ;
this.label1.Name = "label1" ;
this.label1.TabIndex = 4 ;
this.label1.Text = "本地时间:" ;
this.label2.Location = new System.Drawing.Point ( 40 , 88 ) ;
this.label2.Name = "label2" ;
this.label2.Size = new System.Drawing.Size ( 88 , 24 ) ;
this.label2.TabIndex = 5 ;
this.label2.Text = "服务器时间:" ;
this.label3.Location = new System.Drawing.Point ( 16 , 24 ) ;
this.label3.Name = "label3" ;
this.label3.Size = new System.Drawing.Size ( 112 , 23 ) ;
this.label3.TabIndex = 6 ;
this.label3.Text = "设定服务器地址:" ;
this.textBox3.Location = new System.Drawing.Point ( 120 , 24 ) ;
this.textBox3.Name = "textBox3" ;
this.textBox3.Size = new System.Drawing.Size ( 200 , 21 ) ;
this.textBox3.TabIndex = 7 ;
this.textBox3.Text = "" ;
this.AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ;
this.ClientSize = new System.Drawing.Size ( 352 , 245 ) ;
this.Controls.AddRange ( new System.Windows.Forms.Control[] {
this.textBox3 ,
this.textBox2 ,
this.textBox1 ,
this.button2 ,
this.button1 ,
this.label1 ,
this.label2 ,
this.label3} ) ;
this.MaximizeBox = false ;
this.Name = "Form1" ;
this.Text = "UDP对时客户端" ;
this.ResumeLayout ( false ) ;
}
至此【UDP对时客户端】项目的界面设计和程序功能实现的前期工作就基本完成了,其设计界面如图03所示:
图03:【UDP对时客户端】项目的设计界面
13.在Form1.cs中的InitializeComponent过程之后,添加下列代码,下列代码的功能是在程序中导入WinAPI函数——SetSystemTime,这个函数位于文件Kernel32.dll。程序就是通过此函数来更正系统时间的。
[ DllImport ( "Kernel32.dll" )]
private static extern bool SetSystemTime ( SystemTime time ) ;
//引入API函数
14.并把它添加到在导入WinAPI函数代码之后,再添加下列代码,下列代码是定义“start_client”过程。此过程的功能是向服务器端传送对时请求,并获取从服务器端反馈来的时间日期数据。
{
client = new UdpClient ( port ) ;
ipAddress a = IPAddress.Parse ( "127001" ) ;
receivePoint = new IPEndPoint ( a , port ) ;
IPAddress HostIP ;
bool continueLoop = true ;
while ( continueLoop )
{
string hostName = Dns.GetHostName ( ) ;
System.Text.ASCIIEncoding encode
= new System.Text.ASCIIEncoding ( ) ;
//定义发送到服务器端的请求信息
//请求信息是一个字符串,为客户端名称和接收服务器反馈信息的端口号组成的字符串
string sendString = hostName + "/" + port.ToString ( ) ;
byte[] sendData = encode.GetBytes ( sendString ) ;
//判定使用者输入的是IP地址还是计算机名称
try
{
HostIP = IPAddress.Parse ( textBox3.Text ) ;
}
catch
{
//假如输入的是计算机名称,则按照执行下列代码。
//发送请求信息
client.Send ( sendData , sendData.
Length , textBox3.Text , 8080 ) ;
//接收来自服务器端的信息
byte[] recData =
client.Receive ( ref receivePoint ) ;
timeString = encode.GetString ( recData ) ;
client.Close ( ) ;
continueLoop=false ;
return ;
}
//输入的是IP地址,则执行下列代码
IPEndPoint host = new IPEndPoint ( HostIP ,8080 ) ;
//发送请求信息
client.Send ( sendData , sendData.Length , host ) ;
//接收来自服务器端的信息
byte[] recData1 = client.Receive ( ref receivePoint ) ;
//获取服务器端的时间和日期
timeString = encode.GetString ( recData1 ) ;
client.Close ( ) ;
//退出循环
continueLoop=false ;
}
}
假如“start_client”过程正确调用,就把服务器端的时间和日期保存到timeString字符串中了。
17.用下列代码替换Form1.cs中button1的“Click”事件的处理代码。下列代码的功能是调用“start_client”过程,获取并显示服务器端程序的时间和日期信息。
private void button1_Click ( object sender , System.EventArgs e )
{
start_client ( ) ;
textBox1.Text = DateTime.Now.ToString ( ) ;
//显示客户端当前时间和日期
textBox2.Text = timeString ;
//显示服务器当前时间和日期
}
18.用下列代码替换Form1.cs中button2的“Click”事件对应的处理代码。下列代码的功能是根据获取的服务器时间和日期数据来更正客户端时间和日期。
private void button2_Click ( object sender , System.EventArgs e )
{
start_client ( ) ;
//把接收来的数据转换时间日期格式
try
{
temp = DateTime.Parse ( timeString ) ;
}
catch
{
MessageBox.Show ( "错误时间" ) ;
return ;
}
//根据得到的时间日期,来定义时间、日期
SystemTime st= new SystemTime ( ) ;
st.year= ( short )temp.Year ;
st.Month= ( short )temp.Month ;
st.DayOfWeek= ( short )temp.DayOfWeek ;
st.Day= ( short )temp.Day ;
st.Hour=Convert.ToInt16 ( temp.Hour ) ;
if ( st.Hour>=12 )
{
st.Hour-= ( short )8 ;
}
else if ( st.Hour >= 8 )
{
st.Hour-= ( short )8 ;
}
else
{
st.Hour+= ( short )16 ;
}
st.Minute=Convert.ToInt16 ( temp.Minute ) ;
st.Second=Convert.ToInt16 ( temp.Second ) ;
st.Milliseconds=Convert.ToInt16 ( temp.Millisecond ) ;
//修改本地端的时间和日期
if ( SetSystemTime ( st ) )
{
MessageBox.Show ( DateTime.Now.ToString ( ) ,"修改成功" ) ;
}
else
MessageBox.Show ( "不成功!" ,"不成功" ) ;
}
至此,在正确完成上述步骤,全部保存后,【网络对时客户端】项目的全部工作就完成了。
六.运行基于UDP协议网络对时系统,实现网络对时:
首先要确认确认网络对时系统中的服务器端程序已经运行和其IP地址或主机名。然后在客户机上运行网络对时系统中的客户端程序,在正确输入运行网络对时系统服务器端程序对应的主机名或者IP地址后,单击客户端程序中【获取】按钮,则在程序的文本框中显示服务器当前时间和日期和客户端当前的时间和日期。若发现二种存在差异,单击【对时】按钮,则将以服务器当前时间和日期来修正客户机的时间和日期。修改成功则弹出【修改成功】提示框,反之则弹出【不成功】提示框,图04是【UDP对时客户端】项目根据服务器端当前时间和日期信息成功更改本地时间和日期后的界面:
图04:【UDP对时客户端】项目的运行界面
七.总结:
本文具体介绍了UDP协议,.Net FrameWork SDK提供给Visual C#用以操作UDP协议的主要类库,以及通过一个具体而使用的示例——实现一个网络对时系统,介绍在Visual C#实现UDP协议的具体方法和过程。UDP由于其自身的缺点注定在某些领域无法利用它,但在可以利用它的领域,UDP以其快捷、简单、实用的特点正在受到更多程序员的欢迎。尤其在现代,网络运行态势越来越好的情况下,可以预见的是UDP在网络中的应用情景将更广阔。希望本文的内容对您把握用Visual C#编写基于UDP的网络应用程序有所帮助。