编写win32时钟同步犯的低级错误

来源:互联网 发布:网络优化推广 编辑:程序博客网 时间:2024/05/16 14:42

在编写跨平台时钟同步服务时,犯了一个经典低级错误,和大家共同分享

原来函数大概实现是这样的:计算客户端和时间服务器误差delta值(以秒为单位),用该值修正本地时钟

int update(long delta)
{
#ifdef _WIN32
 // use SetLocalTime() to change time
 SYSTEMTIME st;
 FILETIME ft;
 ULARGE_INTEGER ui;
 ::GetLocalTime(&st);
 ::SystemTimeToFileTime(&st,&ft);
 ui.LowPart=ft.dwLowDateTime;
 ui.HighPart=ft.dwHighDateTime;
 ui.QuadPart+=(delta*10000000);
 ft.dwLowDateTime=ui.LowPart;
 ft.dwHighDateTime=ui.HighPart;

 ::FileTimeToSystemTime(&ft,&st);
 if (::SetLocalTime(&st))
 {

//write success log
  return 0;
 }else{

//write fail log
  return -1;
 }

}

 

调试发现当误差超过一定值同步行为就比较诡异了,相信细心的程序员早就发现问题出在哪儿了

下面是修改之后的代码

 

int update(long delta)
{
#ifdef_WIN32
 // use SetLocalTime() to change time
 SYSTEMTIME st;
 FILETIME ft;
 ULARGE_INTEGER ui;
 __int64 delta64=delta;
 ::GetLocalTime(&st);
 ::SystemTimeToFileTime(&st,&ft);
 ui.LowPart=ft.dwLowDateTime;
 ui.HighPart=ft.dwHighDateTime;
 ui.QuadPart+=(delta64*10000000);
 ft.dwLowDateTime=ui.LowPart;
 ft.dwHighDateTime=ui.HighPart;

 ::FileTimeToSystemTime(&ft,&st);
 if (::SetLocalTime(&st))
 {
//write success log
  return 0;
 }else{
//get last error and write fail log
  return -1;
 }

}

 

调试现象就是当客户端和主机误差超过一定范围时,显示同步成功,但是时钟误差并未正确修正,原因比对前后代码就很清楚了

原创粉丝点击