您的位置:首页 > 编程语言 > C#

c# Internet时间服务器同步

2015-11-11 23:32 447 查看

2009-02-02 17:48 8226人阅读 评论(2) 收藏 举报
服务器internetc#socketstringwindows

需要用到的名空间

[c-sharp] view plaincopy

using System.Net;

using System.Net.Sockets;

using System.Runtime.InteropServices;

建立一个结构

[c-sharp] view plaincopy

public struct SystemTime

{

public ushort wYear;

public ushort wMonth;

public ushort wDayOfWeek;

public ushort wDay;

public ushort wHour;

public ushort wMinute;

public ushort wSecond;

public ushort wMilliseconds;

/// <summary>

/// 从System.DateTime转换。

/// </summary>

/// <param name="time">System.DateTime类型的时间。</param>

public void FromDateTime(DateTime time)

{

wYear = (ushort)time.Year;

wMonth = (ushort)time.Month;

wDayOfWeek = (ushort)time.DayOfWeek;

wDay = (ushort)time.Day;

wHour = (ushort)time.Hour;

wMinute = (ushort)time.Minute;

wSecond = (ushort)time.Second;

wMilliseconds = (ushort)time.Millisecond;

}

/// <summary>

/// 转换为System.DateTime类型。

/// </summary>

/// <returns></returns>

public DateTime ToDateTime()

{

return new DateTime(wYear, wMonth, wDay, wHour, wMinute, wSecond, wMilliseconds);

}

/// <summary>

/// 静态方法。转换为System.DateTime类型。

/// </summary>

/// <param name="time">SYSTEMTIME类型的时间。</param>

/// <returns></returns>

public static DateTime ToDateTime(SystemTime time)

{

return time.ToDateTime();

}

}

要用到Windows的API函数来设置系统时间

[c-sharp] view plaincopy

public class Win32API

{

[DllImport("Kernel32.dll")]

public static extern bool SetLocalTime(ref SystemTime Time);

[DllImport("Kernel32.dll")]

public static extern void GetLocalTime(ref SystemTime Time);

}

用Socket获取Internet时间服务器上的时间

[c-sharp] view plaincopy

public void SetInternetTime()

{

// 记录开始的时间

DateTime startDT = DateTime.Now;

//建立IPAddress对象与端口,创建IPEndPoint节点:

int port = 13;

string[] whost = { "5time.nist.gov", "time-nw.nist.gov", "time-a.nist.gov", "time-b.nist.gov", "tick.mit.edu", "time.windows.com", "clock.sgi.com" };

IPHostEntry iphostinfo;

IPAddress ip;

IPEndPoint ipe;

Socket c = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建Socket

c.ReceiveTimeout = 10 * 1000;//设置超时时间

string sEX = "";// 接受错误信息

// 遍历时间服务器列表

foreach (string strHost in whost)

{

try

{

iphostinfo = Dns.GetHostEntry(strHost);

ip = iphostinfo.AddressList[0];

ipe = new IPEndPoint(ip, port);

c.Connect(ipe);//连接到服务器

if (c.Connected) break;// 如果连接到服务器就跳出

}

catch (Exception ex)

{

sEX = ex.Message;

}

}

if (!c.Connected)

{

MessageBox.Show("时间服务器连接失败!/r错误信息:" + sEX, "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

return;

}

//SOCKET同步接受数据

byte[] RecvBuffer = new byte[1024];

int nBytes, nTotalBytes = 0;

StringBuilder sb = new StringBuilder();

System.Text.Encoding myE = Encoding.UTF8;

while ((nBytes = c.Receive(RecvBuffer, 0, 1024, SocketFlags.None)) > 0)

{

nTotalBytes += nBytes;

sb.Append(myE.GetString(RecvBuffer, 0, nBytes));

}

//关闭连接

c.Close();

string[] o = sb.ToString().Split(' '); // 打断字符串

textBox1.Text = sb.ToString();

TimeSpan k = new TimeSpan();

k = (TimeSpan)(DateTime.Now - startDT);// 得到开始到现在所消耗的时间

DateTime SetDT = Convert.ToDateTime(o[1] + " " + o[2]).Subtract(-k);// 减去中途消耗的时间

//处置北京时间 +8时

SetDT = SetDT.AddHours(8);

//转换System.DateTime到SystemTime

SystemTime st = new SystemTime();

st.FromDateTime(SetDT);

//调用Win32 API设置系统时间

Win32API.SetLocalTime(ref st);

MessageBox.Show("时间已同步", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

}

这个东西是收集网上的一些做法再修改了一下

用vs2008+windows xp sp2测试通过

但是始终会有±1秒的误差,但大部分误差在1秒以下,尚可接受

使用的名空间包括vs自己添加的,windows Form中用到的那部分

如果换了环境,可作相应修改

转载:http://blog.csdn.net/zhengxia19/article/details/3858910
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: