c# Internet时间服务器同步

需要用到的名空间

using System.Net;  
using System.Net.Sockets;  
using System.Runtime.InteropServices;  

建立一个结构

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函数来设置系统时间

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时间服务器上的时间

public void SetInternetTime()  
        {  
            // 记录开始的时间  
            DateTime startDT = DateTime.Now;  
  
            //建立IPAddress对象与端口,创建IPEndPoint节点:  
            int port = 13;  
            string[] whost = { "time.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中用到的那部分

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值