iOS 64 位 ntpdate 不能与 arm64 标志一起正常工作

iOS 64bit ntpdate don't work properly with arm64 flag

我有一个函数 (ANSI C) 可以为我们的 ntpd 服务器检索时间。

此代码在我编译 32 位时可以正常工作,但如果我在 armv64 中编译则不起作用。 它在 iPhone 4,4S,5(32 位)上正常工作,在 Iphone 5s,6,6S(64 位)上无法正常工作。

我认为问题是:

tmit=ntohl((time_t)buf[10]); //# get transmit time

time_t 在 armv64 中编译时现在是 8byte.....

您可以在下面找到源代码...

Output Correct with Iphone 5 Simulator (32bit) ---------------------------

xxx.xxx.xxx.xxx PORT 123
sendto-->48
prima recv
recv-->48
tmit=-661900093
tmit=1424078403
1424078403-->Time: Mon Feb 16 10:20:03 2015

10:20:03 --> 37203


---------------------------------------------------------
Output Wrong with Iphone 6 Simulator (64bit) ---------------------------
xxx.xxx.xxx.xxx PORT 123
sendto-->48
prima recv
recv-->48
tmit=19612797
tmit=2105591293
2105591293-->Time: Tue Nov 19 00:47:09     38239
00:47:09 --> 2829
//---------------------------------------------------------------------------
long ntpdate(char *hostname) {

    //ntp1.inrim.it (193.204.114.232)
    //ntp2.inrim.it (193.204.114.233)

    int     portno=NTP_PORT; //NTP is port 123
    int     maxlen=1024;     //check our buffers
    int     i=0;         // misc var i
    unsigned char msg[48]={010,0,0,0,0,0,0,0,0}; // the packet we send
    unsigned long  buf[maxlen]; // the buffer we get back
    //struct in_addr ipaddr; //
    struct protoent *proto; //
    struct sockaddr_in server_addr;
    int s; // socket
    int tmit; // the time -- This is a time_t sort of
    char ora[20]="";


    //
    //#we use the system call to open a UDP socket
    //socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp")) or die "socket: $!";
    proto=getprotobyname("udp");
    s=socket(PF_INET, SOCK_DGRAM, proto->p_proto);
    if(s==-1) {
        //printf("ERROR socket=%d\n",s);
        return -1;
    }

    //Setto il timeout per la ricezione --------------------

    struct timeval          tv;

    tv.tv_sec       = TIMEOUT_NTP; //sec
    tv.tv_usec      = 0;

    if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) != 0)
    {
        //printf("Error assigning socket option");
        return -1;
    }


    memset( &server_addr, 0, sizeof( server_addr ));
    server_addr.sin_family=AF_INET;


    //trasformo il nome in ip
    struct hostent *hp = gethostbyname(hostname);

    if (hp == NULL) {
        return -1;
    } else {
        sprintf(hostname_ip, "%s", inet_ntoa( *( struct in_addr*)( hp -> h_addr_list[0])));

    }
#ifdef LOG_NTP
    printf("%s-->%s PORT %d\n",hostname,hostname_ip,portno);
#endif

    server_addr.sin_addr.s_addr = inet_addr(hostname_ip);
    server_addr.sin_port=htons(portno);

    //printf("ipaddr (in hex): %x\n",server_addr.sin_addr);

    /*
     * build a message.  Our message is all zeros except for a one in the
     * protocol version field
     * msg[] in binary is 00 001 000 00000000
     * it should be a total of 48 bytes long
     */


    // send the data
    i=sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,sizeof(server_addr));
#ifdef LOG_NTP
    printf("sendto-->%d\n",i);
#endif

    if (i==-1)
        return -1;

#ifdef LOG_NTP
    printf("prima recv\n");
#endif

    // get the data back
    i=recv(s,buf,sizeof(buf),0);

#ifdef LOG_NTP
    printf("recv-->%d\n",i);

#endif

    if (i==-1)
    {
#ifdef LOG_NTP
        printf("Error: %s (%d)\n", strerror(errno), errno);
#endif
        return -1;
    }

    //printf("recvfr: %d\n",i);

    //We get 12 long words back in Network order

     //for(i=0;i<12;i++)
     //printf("%d\t%-8x\n",i,ntohl(buf[i]));


    /*
     * The high word of transmit time is the 10th word we get back
     * tmit is the time in seconds not accounting for network delays which
     * should be way less than a second if this is a local NTP server
     */

    tmit=ntohl((time_t)buf[10]); //# get transmit time


#ifdef LOG_NTP
    printf("tmit=%d\n",tmit);
#endif
    /*
     * Convert time to unix standard time NTP is number of seconds since 0000
     * UT on 1 January 1900 unix time is seconds since 0000 UT on 1 January
     * 1970 There has been a trend to add a 2 leap seconds every 3 years.
     * Leap seconds are only an issue the last second of the month in June and
     * December if you don't try to set the clock then it can be ignored but
     * this is importaint to people who coordinate times with GPS clock sources.
     */

    tmit-= 2208988800U;

#ifdef LOG_NTP
    printf("tmit=%d\n",tmit);
#endif
    /* use unix library function to show me the local time (it takes care
     * of timezone issues for both north and south of the equator and places
     * that do Summer time/ Daylight savings time.
     */


    //#compare to system time
#ifdef LOG_NTP
    //printf("%d-->Time: %s\n",tmit,ctime((const time_t)&tmit));
    printf("%d-->Time: %s\n",tmit,ctime((const time_t)&tmit));
#endif


    //i=time(0);
   //printf("%d-%d=%d\n",i,tmit,i-tmit);
    //printf("System time is %d seconds off\n",i-tmit);


    //Prendo l'ora e la converto in HH:MM:SS --> Sec
    strftime(ora, 20, "%T", localtime((const time_t)&tmit));

#ifdef LOG_NTP
    printf("%s --> %ld\n",ora, C2TIME(ora));
#endif  
    return C2TIME(ora);

}

我解决了问题!!!!!!!!!

 uint32_t   buf[maxlen]; 
 uint32_t   tmit;    

 instead of:

 unsigned long  buf[maxlen];
 int tmit;  

正在定义类型为 time_t

的变量
time_t tmit_temp=tmit;
printf("%d-->Time: %s\n",tmit,ctime((const time_t)&tmit_temp));
strftime(ora, 20, "%T", localtime((const time_t)&tmit_temp));

这工作正常!!! ;-)