ACE代碼示例:實現計算機網絡授時的小程序

文/江濤

應用說明

 

本代碼實現了RFC 868 客戶端。啓動程序,向給定的時間服務建立TCP連接,時間服務返回4個字節的整數,這個數定是從1900年1月1日零點到當前時間過去的秒數,當然它是網絡字節的順序的,通過網絡字節到主機字節轉換後,我們就可以讀出這個數字。

本程序暫只支持Windows,因爲linux下的修改系統時間和Windows的接口不一致,linux下的同學可以自行修改代碼。

 

 

//timeclient.cpp
//platform: win32

#include "ace/Log_Msg.h"
#include "ace/Time_Value.h"
#include "ace/OS.h"
#include "ace/Date_Time.h"
#include "ace/streams.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Connector.h"
#include "ace/SOCK_Stream.h"
#include "ace/Get_Opt.h"
#include <string>
using namespace std;
#ifdef WIN32
#include <windows.h>
#endif
#if 0
//可用的部分服務器地址
#define NUMSRV 15
char *serv_ip[NUMSRV]= {"64.236.96.53"   ,/*nist1.aol-va.truetime.com*/
"128.138.140.44" ,/*utcnist.colorado.edu*/
"207.200.81.113" ,/*nist1.aol-ca.truetime.com*/
"216.200.93.8"   ,/*nist1-dc.glassey.com*/
"63.149.208.50"  ,/*nist1.datum.com*/
"208.184.49.9"   ,/*nist1-ny.glassey.com*/
"207.126.103.204",/*nist1-sj.glassey.com*/
"129.6.15.28"    ,/*time-a.nist.gov*/
"129.6.15.29"    ,/*time-b.nist.gov*/
"132.163.4.101"  ,/*time-a.timefreq.bldrdoc.gov*/
"132.163.4.102"  ,/*time-b.timefreq.bldrdoc.gov*/
"132.163.4.103"  ,/*time-c.timefreq.bldrdoc.gov*/
"192.43.244.18"  ,/*time.nist.gov*/
"131.107.1.10"   ,/*time-nw.nist.gov*/ 
"utcnist.colorado.edu"/*DNS entry =128.138.140.44*/
};
#endif

#ifdef WIN32
void TimetToSystemTime( time_t t, LPSYSTEMTIME pst )
{
    FILETIME ft;
    LONGLONG ll = Int32x32To64(t, 10000000) + 116444736000000000;
    ft.dwLowDateTime = (DWORD) ll;
    ft.dwHighDateTime = (DWORD)(ll >> 32);

    FileTimeToSystemTime( &ft, pst );
}

int setSysteTime(const time_t&  t)
{
    SYSTEMTIME st;
    memset(&st,0,sizeof(st));
    TimetToSystemTime(t,&st);
    if (::SetSystemTime(&st))
    {
        ::SendMessage(HWND_BROADCAST, WM_TIMECHANGE, 0, 0);
        return 0;
    }
    return -1;

}
#endif
int ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
    ACE_SOCK_Stream peer;
    ACE_SOCK_Connector conn;
    ACE_UINT32 tempValue = 0;
    ACE_INET_Addr address ;
    //(37,);
    string server = "nist1-la.ustiming.org";
    ACE_Get_Opt get_opts (argc, argv, ACE_LIB_TEXT("s:?"));
    int ich;
    while ((ich = get_opts ()) != EOF) {
        switch (ich) {
          case /'s/': /* u specifies that UDP should be used */
              server  = get_opts.opt_arg();
              break;
          case /'?/': /* t specifies that zero copy read should be used */
              cout << "usage:  timeclient -s //"nist1-la.ustiming.org//"" << endl;
             return -1;

          default: /* no parameters */
              break;
        }
    }

    address.set(37,server.c_str());

    if (-1 ==conn.connect(peer,address))
    {
        ACE_ERROR_RETURN((LM_ERROR,
            "%p",
            "connect"),-1);
    }
    ssize_t n = peer.recv((char*) &tempValue,4);
    if (n > 0)
    {
        //字節序從網絡轉爲主機

        tempValue = ntohl(tempValue);
        tempValue -= 2208988800l; ///*subtract 1970.0 - 1900.0*/
        time_t t(tempValue);   
        if (setSysteTime(t) == 0)
        {
            cout << " adjtime OK." << endl;
        }
        else
        {
            cout << " adjtime error" << endl;
        }    
    }

    peer.close();

    time_t lt;
    lt =time(NULL);
    char* ss = ctime(&lt);
    cout << "the system time " <<  ss << endl;   
    return 0;
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章