#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <time.h>
//宏定义
#define JAN_1970 0x83aa7e80
#define NTPFRAC(x) (4294 * (x) + ((1981 * (x))>>11))
#define USEC(x) (((x) >> 12) - 759 * ((((x) >> 10) + 32768) >> 16))
#define Data(i) ntohl(((unsigned int *)data)[i])
#define LI 0
#define VN 3
#define MODE 3
#define STRATUM 0
#define POLL 4
#define PREC -6
struct NtpTime
{
unsigned int coarse;
unsigned int fine;
};
void getNewTime(unsigned int *data,struct timeval *ptimeval)
{
struct NtpTime trantime;
trantime.coarse = Data(10);
trantime.fine = Data(11);
ptimeval->tv_sec = trantime.coarse - JAN_1970;
ptimeval->tv_usec = USEC(trantime.fine);
}
void NTP_Func(char *ntps)
{
uint8_t i;
unsigned int buf[12];
uint32_t local_timestamp;
struct tm * Net_time;
uint8_t NTP_Data[48]; //48字节的报文
struct timeval now;
struct timeval TimeSet;
for(i=0;i<48;i++)NTP_Data[i]=0;//剩余的47字节为0
NTP_Data[0] = htonl((LI << 30) | (VN << 27) | (MODE << 24) | (STRATUM << 16) | (POLL << 8) | (PREC & 0xff));//构造协议头部信息
NTP_Data[1] = htonl(1<<16); NTP_Data[2] = htonl(1<<16);
gettimeofday(&now, NULL);
NTP_Data[10] = htonl(now.tv_sec + JAN_1970);//构造传输时间戳
NTP_Data[11] = htonl(NTPFRAC(now.tv_usec));
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(socket<0)
{
printf("socket:创建socket套接字失败!\n");
exit(0);
}
socklen_t addrlen = sizeof(struct sockaddr_in);
struct sockaddr_in clientaddr;
clientaddr.sin_port = ntohs(123);
clientaddr.sin_addr.s_addr = inet_addr(ntps);
clientaddr.sin_family = AF_INET;
sendto(sockfd, NTP_Data, sizeof(NTP_Data), 0, (struct sockaddr *)&clientaddr, sizeof(struct sockaddr_in));
printf("send success\n");
recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&clientaddr, &addrlen);
printf("recvfrom success\n");
getNewTime(buf,&TimeSet);
printf("sec = %ld usec = %ld\n",TimeSet.tv_sec ,TimeSet.tv_usec);
Net_time =localtime(&TimeSet.tv_sec);
printf("%d-%d-%d %d:%d:%d\r\n",(Net_time->tm_year)+1900, (Net_time->tm_mon)+1, Net_time->tm_mday, Net_time->tm_hour,Net_time->tm_min,Net_time->tm_sec); //打印出时间
}
int main(int argc,char **argv)
{
if(argc!=2)
{
printf("erro fomat ./a.out ntpsip \n");
return 0;
}
while(1)
{
NTP_Func(argv[1]);
sleep(1);
}
return 0;
}
使用方法
./app “ntpip”
例:./a.out 120.25.115.20