大家好,又见面了,我是你们的朋友全栈君。
最近做个项目,想通过公网上的NTP服务器给板子校时,但是板子里没有ntpdate这个命令,
下面是2个解决方法,
1,找到ntpdate源代码,重新编译之后,手动运行,
这个方法我上网上查了,比较复杂,据说NTP还与SSL有关,编译的时候必须把SSL也包含进去,于是就迟迟没有动工。
2,突然有一天看到rtthread里也提供一个ntp的客户端,比较简单,就一个文件,也没几行,于是想着把这个.c文件移植到linux下,但我仔细研究了一下,发现这个文件的原始作者就是在linux下设计的。原始文件更简单,就几行代码
就是下面的代码,很简单,于是果断移植这个程序,顺利的实现了校时。其实ntp协议也很简单。关键是这个结构体
int main( void )
{
int sockfd, n; // Socket file descriptor and the n return result from writing/reading from the socket.
int portno = 123; // NTP UDP port number.
//char* host_name = “us.pool.ntp.org”; // NTP server host-name.
char* host_name = “cn.ntp.org.cn”; // NTP server host-name.
typedef struct
{
uint8_t li_vn_mode; // Eight bits. li, vn, and mode.
// li. Two bits. Leap indicator.
// vn. Three bits. Version number of the protocol.
// mode. Three bits. Client will pick mode 3 for client.
uint8_t stratum; // Eight bits. Stratum level of the local clock.
uint8_t poll; // Eight bits. Maximum interval between successive messages.
uint8_t precision; // Eight bits. Precision of the local clock.
uint32_t rootDelay; // 32 bits. Total round trip delay time.
uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
uint32_t refId; // 32 bits. Reference clock identifier.
uint32_t refTm_s; // 32 bits. Reference time-stamp seconds.
uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second.
uint32_t origTm_s; // 32 bits. Originate time-stamp seconds.
uint32_t origTm_f; // 32 bits. Originate time-stamp fraction of a second.
uint32_t rxTm_s; // 32 bits. Received time-stamp seconds.
uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second.
uint32_t txTm_s; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second.
} ntp_packet; // Total: 384 bits or 48 bytes.
// Create and zero out the packet. All 48 bytes worth.
ntp_packet packet = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
memset( &packet, 0, sizeof( ntp_packet ) );
// Set the first byte’s bits to 00,011,011 for li = 0, vn = 3, and mode = 3. The rest will be left set to zero.
*( ( char * ) &packet + 0 ) = 0x1b; // Represents 27 in base 10 or 00011011 in base 2.
struct sockaddr_in serv_addr; // Server address data structure.
struct hostent *server; // Server data structure.
sockfd = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); // Create a UDP socket.
if ( sockfd < 0 )
error( “ERROR opening socket” );
server = gethostbyname( host_name ); // Convert URL to IP.
if ( server == NULL )
error( “ERROR, no such host” );
// Zero out the server address structure.
bzero( ( char* ) &serv_addr, sizeof( serv_addr ) );
serv_addr.sin_family = AF_INET;
// Copy the server’s IP address to the server address structure.
bcopy( ( char* )server->h_addr, ( char* ) &serv_addr.sin_addr.s_addr, server->h_length );
serv_addr.sin_port = htons( portno );
// Call up the server using its IP address and port number.
if ( connect( sockfd, ( struct sockaddr * ) &serv_addr, sizeof( serv_addr) ) < 0 )
error( “ERROR connecting” );
n = write( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
if ( n < 0 )
error( “ERROR writing to socket” );
// Wait and receive the packet back from the server. If n == -1, it failed.
n = read( sockfd, ( char* ) &packet, sizeof( ntp_packet ) );
if ( n < 0 )
error( “ERROR reading from socket” );
packet.txTm_s = ntohl( packet.txTm_s ); // Time-stamp seconds.
packet.txTm_f = ntohl( packet.txTm_f ); // Time-stamp fraction of a second.
time_t txTm = ( time_t ) ( packet.txTm_s – NTP_TIMESTAMP_DELTA );
// Print the time we got from the server, accounting for local timezone and conversion from UTC time.
txTm = txTm + 8*60*60; //willow add
printf( “Time: %s”, ctime( ( const time_t* ) &txTm ) );
set_time_t(txTm); //willow add 200924
LOG_F(“set time from NTP:%s\r”, ctime(&(txTm)));
return 0;
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/150100.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...