分享
 
 
 

使用UDP实现一个时钟服务器

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在网站上实现时钟同步的操作是很常见的。这里以UDP方式来实现一个。其中会调用到WINAPI

using System ;

using System.Drawing ;

using System.Collections ;

using System.ComponentModel ;

using System.Windows.Forms ;

using System.Data ;

using System.Net ;

using System.Net.Sockets ;

using System.Threading ;

//程序中使用到线程

using System.Text ;

//程序中使用到编码

namespace UDPTimerServer{

/// <summary>

/// Form1 的摘要说明。

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.Label label1;

private System.Windows.Forms.ListBox listBox1;

private System.Windows.Forms.Button button1;

private UdpClient server ;

private IPEndPoint receivePoint ;

private int port = 10000 ;

//定义端口号

private int ip = 127001 ;

//设定本地IP地址

private Thread startServer ;

/// <summary>

/// 必需的设计器变量。

/// </summary>

private System.ComponentModel.Container components = null;

public Form1()

{

//

// Windows 窗体设计器支持所必需的

//

InitializeComponent();

//

// TODO: 在 InitializeComponent 调用后添加任何构造函数代码

//

}

/// <summary>

/// 清理所有正在使用的资源。

/// </summary>

protected override void Dispose( bool disposing )

{

try

{

//关闭线程

startServer.Abort ( ) ;

//清除资源

server.Close ( ) ;

}

catch

{

} ;

if ( disposing )

{

if ( components != null )

{

components.Dispose ( ) ;

}

}

base.Dispose ( disposing ) ;

}

#region Windows 窗体设计器生成的代码

/// <summary>

/// 设计器支持所需的方法 - 不要使用代码编辑器修改

/// 此方法的内容。

/// </summary>

private void InitializeComponent()

{

this.listBox1 = new System.Windows.Forms.ListBox ( ) ;

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

this.button1 = new System.Windows.Forms.Button ( ) ;

this.SuspendLayout ( ) ;

this.listBox1.ItemHeight = 12 ;

this.listBox1.Location = new System.Drawing.Point ( 14 , 40 ) ;

this.listBox1.Name = "listBox1" ;

this.listBox1.Size = new System.Drawing.Size ( 268 , 220 ) ;

this.listBox1.TabIndex = 0 ;

this.label1.ForeColor = System.Drawing.Color.Red ;

this.label1.Location = new System.Drawing.Point ( 44 , 10 ) ;

this.label1.Name = "label1" ;

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

this.label1.TabIndex = 1 ;

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

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

this.button1.Location = new System.Drawing.Point ( 106 , 278 ) ;

this.button1.Name = "button1" ;

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

this.button1.TabIndex = 2 ;

this.button1.Text = "清除信息" ;

this.button1.Click += new System.EventHandler ( this.button1_Click ) ;

this.AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ;

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

this.Controls.AddRange ( new System.Windows.Forms.Control[] {

this.button1 ,

this.listBox1 ,

this.label1} ) ;

this.MaximizeBox = false ;

this.Name = "Form1" ;

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

this.Load += new System.EventHandler ( this.Form1_Load ) ;

this.ResumeLayout ( false ) ;

}

#endregion

/// <summary>

/// 应用程序的主入口点。

/// </summary>

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

private void Form1_Load(object sender, System.EventArgs e)

{

Run();

}

// 请注意:下面代码中约定客户机程序发送对时请求信息到服务器的8080端口号。

// 服务器端程序接收发送到本地8080端口号的数据就完成了数据接收。

// 为了能够让服务器端程序知道是那台客户机提出请求和要把对时信息发送到客户机的那个端口号上,

// 客户端程序对发送的对时请求信息进行了设计。客户端的对时请求信息结构为:

//

// 计算机名称 + / + 客户机接收信息端口号

//

// 这样如果客户端计算机名称为:greystar,接收服务器端时间数据的端口号是1000,

// 则客户端程序发送的对时请求数据就为:greystar/1000。

//

// 服务器端程序在接收到客户端对时请求数据,并进行分析后,

// 就能够通过UdpClient类的Send方法准确的把服务器端当前的时间和日期发送到客户端指定的端口号上。

// 这样客户端程序通过读取指定的端口号,就能够获得服务器端当前的时间和日期,

// 从而以此来修正客户端的时间和日期了。

public void start_server ( )

{

while ( true )

{

//接收从远程主机发送到本地8080端口的数据

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

ASCIIEncoding encode = new ASCIIEncoding ( ) ;

//获得客户端请求数据

string Read_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] ) ) ;

}

}

public void Run ( )

{

//利用本地8080端口号来初始化一个UDP网络服务

server = new UdpClient ( port ) ;

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

//开一个线程

startServer = new Thread ( new ThreadStart ( start_server ) ) ;

//启动线程

startServer.Start ( ) ;

}

private void button1_Click(object sender, System.EventArgs e)

{

listBox1.Items.Clear ( ) ;

}

}

}

using System;

using System.Drawing;

using System.Collections ;

using System.ComponentModel ;

using System.Windows.Forms ;

using System.Data ;

using System.Net ;

using System.Net.Sockets ;

using System.Runtime.InteropServices ;

//客户端程序

namespace UDPTimerClient

{

/// <summary>

/// Form1 的摘要说明。

/// </summary>

public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.TextBox textBox1;

private System.Windows.Forms.TextBox textBox2;

private System.Windows.Forms.TextBox textBox3;

private System.Windows.Forms.Button button1;

private System.Windows.Forms.Button button2;

private System.Windows.Forms.Label label1;

private System.Windows.Forms.Label label2;

private UdpClient client ;

//创建UDP网络服务

private IPEndPoint receivePoint ;

private int port = 8080 ;

//定义接收服务器端程序发送对时信息对应的端口号

private string timeString = DateTime.Now.ToString ( ) ;

//存放时间日期信息字符串

private DateTime temp ;

private System.Windows.Forms.Label label3;

//定义一个时间类型,用以修改当前时间和日期

/// <summary>

/// 必需的设计器变量。

/// </summary>

private System.ComponentModel.Container components = null;

[ DllImport ( "Kernel32.dll" )]

private static extern bool SetSystemTime ( SystemTime time ) ;

public Form1()

{

//

// Windows 窗体设计器支持所必需的

//

InitializeComponent();

//

// TODO: 在 InitializeComponent 调用后添加任何构造函数代码

//

}

/// <summary>

/// 清理所有正在使用的资源。

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region Windows 窗体设计器生成的代码

/// <summary>

/// 设计器支持所需的方法 - 不要使用代码编辑器修改

/// 此方法的内容。

/// </summary>

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();

//

// button1

//

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);

//

// button2

//

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);

//

// textBox1

//

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 = "";

//

// textBox2

//

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 = "";

//

// label1

//

this.label1.Location = new System.Drawing.Point(48, 56);

this.label1.Name = "label1";

this.label1.TabIndex = 4;

this.label1.Text = "本地时间:";

//

// label2

//

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 = "服务器时间:";

//

// label3

//

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 = "设定服务器地址:";

//

// textBox3

//

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 = "";

//

// Form1

//

this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

this.ClientSize = new System.Drawing.Size(352, 245);

this.Controls.Add(this.textBox3);

this.Controls.Add(this.textBox2);

this.Controls.Add(this.textBox1);

this.Controls.Add(this.button2);

this.Controls.Add(this.button1);

this.Controls.Add(this.label1);

this.Controls.Add(this.label2);

this.Controls.Add(this.label3);

this.MaximizeBox = false;

this.Name = "Form1";

this.Text = "UDP对时客户端";

this.ResumeLayout(false);

}

#endregion

/// <summary>

/// 应用程序的主入口点。

/// </summary>

[STAThread]

static void Main()

{

Application.Run(new Form1());

}

[StructLayout(LayoutKind.Sequential )]

public class SystemTime

{

public short year ;

public short Month ;

public short DayOfWeek ;

public short Day ;

public short Hour ;

public short Minute ;

public short Second ;

public short Milliseconds ;

}

//定义系统时间的结构

void Start()

{

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

{

//如果输入的是计算机名称,则按照执行下列代码。

//发送请求信息,服务器端口定为10000

client.Send ( sendData , sendData.

Length , textBox3.Text , 10000 ) ;

//接收来自服务器端的信息

byte[] recData =

client.Receive ( ref receivePoint ) ;

timeString = encode.GetString ( recData ) ;

client.Close ( ) ;

continueLoop=false ;

return ;

}

//输入的是IP地址,则执行下列代码

IPEndPoint host = new IPEndPoint ( HostIP ,10000 ) ;

//发送请求信息

client.Send ( sendData , sendData.Length , host ) ;

//接收来自服务器端的信息

byte[] recData1 = client.Receive ( ref receivePoint ) ;

//获取服务器端的时间和日期

timeString = encode.GetString ( recData1 ) ;

client.Close ( ) ;

//退出循环

continueLoop=false ;

}

}

private void button1_Click(object sender, System.EventArgs e)

{

Start ( ) ;

textBox1.Text = DateTime.Now.ToString ( ) ;

//显示客户端当前时间和日期

textBox2.Text = timeString ;

//显示服务器当前时间和日期

}

private void button2_Click(object sender, System.EventArgs e)

{

Start ( ) ;

//把接收来的数据转换时间日期格式

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 ( "不成功!" ,"不成功" ) ;

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有