zoukankan      html  css  js  c++  java
  • 获取网络时间

    这两天有一个应用须要获取网络时间。尽管一直知道能够从时间server获取时间,却从来也没有操作过。借这个机会又一次进行一下深入了了解。

    主要的思路就是:通过SOCKET连接时间server,直接接收从server发送的过来的时间数据。

    void GetNetTime()
    {
        TIME_ZONE_INFORMATION tzinfo;
        DWORD dwStandardDaylight;
        int nRet;
    
        /* Initialize Winsock */
        WORD wVersionRequested;
        WSADATA wsaData;
        int nErrCode;
    
        wVersionRequested = MAKEWORD(2, 2);
        nErrCode = WSAStartup(wVersionRequested, &wsaData);
        if (0 != nErrCode)
        {
            return;
        }
    
        /* Get server IP */
        struct hostent *host;
        char *pServerIP;
    
        host = gethostbyname("time.nist.gov");
        if (NULL == host)
        {
            return -1;
        }
    
        pServerIP = inet_ntoa(*(struct in_addr*)host->h_addr_list[0]);
    
        /* Connect to time server, and get time */
        SOCKET sockfd;
    
        char cTimeBuf[40] = { 0 };
        unsigned long ulTime = 0;
        int nTry = 0;
    
        do 
        {
            if (5 == nTry++)
            {
                return -1;
            }
    
            sockfd = socket(AF_INET, SOCK_STREAM, 0);
            if (INVALID_SOCKET == sockfd)
            {
                continue;
            }
    
            int TimeOut = 3000;//设置接收超时6秒
            setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&TimeOut, sizeof(TimeOut));
    
            sockaddr_in    addr;
    
            memset(&addr, 0, sizeof(addr));
            addr.sin_family         = AF_INET;
            addr.sin_port           = htons(37);
            addr.sin_addr.s_addr    = inet_addr(pServerIP);
    
            nRet = connect(sockfd, (sockaddr *)&addr, sizeof(addr));
            if (SOCKET_ERROR == nRet)
            {
                continue;
            }
    
            nRet = recv(sockfd, (char *)&ulTime, sizeof(ulTime), 0);
            if ((SOCKET_ERROR != nRet) && (0 != nRet))
            {
                break;
            }
    
            int nErr = WSAGetLastError();
            TRACE(_T("[%d]%s"), nErr, ConvertErrcodeToString(nErr));
    
            closesocket(sockfd);
        } while (1);
    
        closesocket(sockfd);
    
        unsigned long ulTimehl = ntohl(ulTime);
        ConvertTime(ulTimehl);
    }   
    
    
    

    void ConvertTime(unsigned long ulTime)
    {
        // Windows文件时间是一个64位的值,它是从1601年1月1日中午12:00到如今的时间间隔。
        // 单位是1/10,000,000秒。即1000万分之1秒(100-nanosecond)
        FILETIME ft;
        SYSTEMTIME st;
    
        // 首先将基准时间(1900年1月1日0点0分0秒0毫秒)转化为Windows文件时间
        st.wYear = 1900;
        st.wMonth = 1;
        st.wDay = 1;
        st.wHour = 0;
        st.wMinute = 0;
        st.wSecond = 0;
        st.wMilliseconds = 0;
    
        SystemTimeToFileTime(&st, &ft);
    
        // 然后将Time Protocol使用的基准时间加上逝去的时间(ulTime)
        LONGLONG *pLLong = (LONGLONG *)&ft;
    
        /* 注意:
           文件时间单位是1/1000 0000秒(即100ns)。
           须要将从时间server上获取的以秒为单位的ulTime做一下转换
        */
        *pLLong += (LONGLONG) 10000000 * ulTime;
    
        // 再将时间转化回来。更新系统时间
        FileTimeToSystemTime(&ft, &st);
    
        TRACE(_T("%04d%02d%02d %02d:%02d:%02d
    "), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond );
    
        return;
    }

    各地时差都不一致,能够依据GetTimeDiff函数计算当地时差,对上面的时间加以调整:

    void GetTimeDiff()
    {
        float bias;
        long sminute,shour;
     
    
        /* 获取时区信息 */
        dwStandardDaylight = GetTimeZoneInformation(&tzinfo); //获取时区与UTC的时间差 应该返回-8
        if (dwStandardDaylight == TIME_ZONE_ID_INVALID) //函数运行失败
        {
            return; 
        }
    
        /* 时差调整 */
        bias = tzinfo.Bias;
        if (dwStandardDaylight == TIME_ZONE_ID_STANDARD) //标准时间有效
            bias += tzinfo.StandardBias;
    
        if (dwStandardDaylight == TIME_ZONE_ID_DAYLIGHT) //夏令时间
            bias += tzinfo.DaylightBias;
    
        shour   = bias / 60;
        sminute = fmod(bias, (float)60);
    }

    
    


  • 相关阅读:
    mysql远程连接失败的解决方法(CentOS版)
    【lamp】搭建
    【wamp】WAMP配置与单IP多域名功能设置
    【centos】网卡自动联网
    stm32之keil开发环境搭建
    利用ffmpeg将H264流 解码为RGB 分类: VC++ ffmpeg-SDL-VLC-Live555 2015-08-07 11:39 155人阅读 评论(0) 收藏
    使用ffserver实现转发实时流媒体(摄像头捕获) 分类: TI-AM335X arm-linux-Ubuntu ffmpeg-SDL-VLC-Live555 2015-08-04 09:36 5人阅读 评论(0) 收藏
    ffmpeg+ffserver搭建流媒体服务器 分类: arm-linux-Ubuntu ffmpeg-SDL-VLC-Live555 TI-AM335X 2015-08-04 09:35 6人阅读 评论(0) 收藏
    嵌入式linux------ffmpeg移植 编码H264(am335x编码H264) 分类: TI-AM335X ffmpeg-SDL-VLC-Live555 arm-linux-Ubuntu 2015-08-04 09:34 5人阅读 评论(0) 收藏
    嵌入式linux------ffmpeg移植 解码H264(am335x解码H264到yuv420并通过SDL显示) 分类: arm-linux-Ubuntu TI-AM335X ffmpeg-SDL-VLC-Live555 2015-07-29 10:28 154人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6951358.html
Copyright © 2011-2022 走看看