为什么ntp服务器不响应我的客户端请求?

时间:2015-12-03 00:22:42

标签: c linux ntp

所以我创建了一个sntp客户端,并尝试在可靠的ntp服务器上测试它。我的客户端正在发送请求,然后服务器应该用它自己的时间戳进行响应,然后客户端计算往返延迟等。但是当我的客户端发送请求时它什么都没有回来,我真的不知道为什么会这样适用于我创建的sntp服务器。我查看了线鲨,看看发生了什么,客户端的请求看起来很好,服务器的响应也是如此,所以我不确定发生了什么!下面是客户端代码:

/* talker.c
* run the program and enter hostname on command line
* e.g ./talker localhost
* Author: Adam Gloyne (14012913)
* Purpose: Sends request to server and calculates received time stamps
* Date Edited: 01/12/15 - added comments
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <time.h> //for time calcs
/* server port the client connects to */
#define PORT 123
#define MAXBUFLEN 100

int main( int argc, char * argv[]) {
/**Variables **********************************/ 
/* for gethostbyname() */
struct hostent *he;
struct sockaddr_in their_addr;
int sockfd, numbytes, addr_len;
char buf[ MAXBUFLEN];
//variables for time processing ***
struct tm * timer;
char message [64];
char format [64];
long long t1; //originate time stamp
long long t2; //transmit time stamp
long long t3; //receive time stamp
long long t4; //final time stamp
long long roundDelay;
long long offset;
time_t secs; //microseconds for calcs
//***********************************
/***********************************************/

/* server address info */
if( argc != 2) {
fprintf( stderr, "usage: talker hostname message\n");
exit( 1);
}
/* resolve server host name or IP address */
if( (he = gethostbyname( argv[1])) == NULL) {
perror( "Talker gethostbyname");
exit( 1);
}
if( (sockfd = socket( AF_INET, SOCK_DGRAM, 0)) == -1) {
perror( "Talker socket");
exit( 1);
}
memset( &their_addr,0, sizeof(their_addr));
/* zero struct */
their_addr.sin_family = AF_INET;    
/* host byte order .. */
their_addr.sin_port = htons( PORT);
/* .. short, netwk byte order */
their_addr.sin_addr = *((struct in_addr *)he -> h_addr);


//get system time *********************************************
time (&secs);
timer = localtime (&secs);
//format time and place into buffer ready to send to server
strftime (format,64,"Client Originate Timestamp  %y-%m-%d %H:%M:%S.\n",timer);
snprintf (message,64,format,(unsigned long)secs); //casting secs
printf (message);

t1 = ntohl((time_t)buf[10]); //get the originate time stamp, needed for final calculation at the end

t1 -= 2208988800U; //converting from ntp to unix time, difference in seconds from ntp time 0h 1st Jan 1900 and unix time 0h 1st Jan 1970 (from RFC)
//********************************************************************

//send the message and check for errors
if( (numbytes = sendto( sockfd, message, strlen(message) + 1, 0,
(struct sockaddr *)&their_addr, sizeof( struct sockaddr))) == -1) {
perror( "Talker sendto");
exit( 1);
}
printf( "Sent %d bytes to %s\n", numbytes,
inet_ntoa( their_addr.sin_addr));


//receive response from server and check for errors
//will be receiving one time stamp from the server but will be the value for both receive and transmit
 addr_len = sizeof (struct sockaddr);
 if( (numbytes = recvfrom( sockfd, buf, MAXBUFLEN - 1, 0,
 (struct sockaddr *)&their_addr, &addr_len)) == -1); {
 perror( "Talker recvfrom");
 //exit( 1);
 }
 //print out received message from server
 printf( "Packet contains \"%s\"\n", buf);

 t3 = ntohl((time_t)buf[10]); //get the server receive time time

 t3 -= 2208988800U; //convert from ntp to unix time

 //assigning transmit stamp from server the same as receive (as specified in RFC)
 t2 = t3;


 //get new system time for final time stamp
 secs = 0;
 time (&secs);
 timer = localtime (&secs);
 strftime (format,64,"\nClient Recieve Timestamp  %y-%m-%d %H:%M:%S.%%06lu %z\n",timer);
 snprintf (message,64,format,(unsigned long)secs); //casting secs
 printf(message);

 t4 = ntohl((time_t)message[10]); //get the client receieve time

 t4 -= 2208988800U; //convert to unix time

 //now we have all time stamps can work out round trip delay and offset
 //round trip first d = (T4 - T1) - (T3 - T2)
 roundDelay = ((t4-t1) - (t3 - t2));
 printf("\nHere is the round trip delay: %d microseconds", roundDelay);

 //now we can calculate the system clock offset.
 //t = ((T2  -T1) + (T3 -T4)) / 2
 offset = ((t2 - t1) + (t3 - t4)) / 2;
 printf("\nHere is the system clock offset: %d microseconds\n", offset);

 //all is done here so close socket and kill client
 close( sockfd);
 return 0;
 }

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

与我的代码交叉核对,它正在运行第4版。

//SNTP Client  

#include <inttypes.h>   //(since C99)   Format conversion of integer types
#include <stdio.h>      //Input/output example printf
#include <stdlib.h>     //General utilities: memory management, program utilities, string conversions, random numbers
#include <unistd.h>     //standard symbolic constants and types
#include <string.h>     //string operations
#include <sys/types.h>  //data types
#include <sys/socket.h> //Internet Protocol family
#include <netinet/in.h> //Internet address family
#include <netdb.h>      //definitions for network database operations
#include <time.h>       //time types
#include <sys/time.h>   //time types
#include <arpa/inet.h>  //definitions for internet operations
//#include<linux/time.h>//time types in linux



//struct for gettimeofday
typedef struct {
    long tv_sec;
    long tv_usec;
} timeval;


struct packets
{
    uint8_t LIVNMODE; 
    uint8_t startum; 
    uint8_t poll; 
    uint8_t precision; 
    uint32_t Root_Delay; 
    uint32_t Root_Dispersion; 
    uint32_t Ref_Identifier; 
    uint32_t Ref_T; 
    uint32_t Ref_Tp2; 
    uint32_t Origin_T;  
    uint32_t Origin_Tp2; 
    uint32_t Receive_T; 
    uint32_t Receive_Tp2; 
    uint32_t T_T; 
    uint32_t T_Tp2; 
};


int main(int argc, char *argv[])
{
int sock_desc;
socklen_t len; 
int today_time;

struct sockaddr_in Cli_addr,Serv_addr; 
struct packets message_send;
struct packets message_receive; 

//add all packets in initialization 
//LI, VN and MODE in a one bytes as a 00 100 011 eg VN=4
message_send.LIVNMODE=0b00100011; 
message_send.startum=0;
message_send.poll=0;
message_send.precision=0;
message_send.Root_Delay=0;
message_send.Root_Dispersion=0;
message_send.Ref_Identifier=0;
message_send.Ref_T=0;
message_send.Ref_Tp2=0;
message_send.Origin_T=0;
message_send.Origin_Tp2=0;
message_send.Receive_T=0;
message_send.Receive_Tp2=0;
message_send.T_T=0;
message_send.T_Tp2=0;


message_receive.Ref_T=0;
message_receive.Ref_Tp2=0;
message_receive.Origin_T=0;
message_receive.Origin_Tp2=0;
message_receive.Receive_T=0;
message_receive.Receive_Tp2=0;
message_receive.T_T=0;
message_receive.T_Tp2=0;
char * HOSTADDRESS;
int PORT;

if (argc>=2){
      HOSTADDRESS=(char *)argv[1]; 
      PORT = atoi(argv[2]);
}
else{
    printf("--------------------------------------------\n");
    printf("usage: ./file.out HOST_ADDRESS PORT \n");
    printf("--------------------------------------------\n");
    return -1;
}


if ((sock_desc = socket(AF_INET,SOCK_DGRAM,0)) < 0){
    printf("Error: can't create the socket ");
    return -1; 
}


len=sizeof(struct sockaddr_in);   
bzero((char *) &Serv_addr,sizeof(Serv_addr));    
Serv_addr.sin_family = AF_INET; 
Serv_addr.sin_addr.s_addr=inet_addr(HOSTADDRESS); 
Serv_addr.sin_port=ntohs(PORT);    


if(sendto(sock_desc,&message_send,sizeof(message_send),0,(struct sockaddr *)&Serv_addr,len) < 0){
     printf("Error: can not send a message on a socket");
     return -1;
}

if(recvfrom(sock_desc,&message_receive,sizeof(message_receive),0,(struct sockaddr *)&Cli_addr,&len) < 0){
     printf("Error: can not receive a message on a socket");
     return -1;
}
printf("message_receive.Ref_T: %" PRIu32 "\n",message_receive.Ref_T);
printf("message_receive.Ref_Tp2: %" PRIu32 "\n",message_receive.Ref_Tp2);
printf("message_receive.Origin_T: %" PRIu32 "\n",message_receive.Origin_T);
printf("message_receive.Origin_Tp2: %" PRIu32 "\n",message_receive.Origin_Tp2);
printf("message_receive.Receive_T: %" PRIu32 "\n",message_receive.Receive_T);
printf("message_receive.Receive_Tp2: %" PRIu32 "\n",message_receive.Receive_Tp2);
printf("message_receive.T_T: %" PRIu32 "\n",message_receive.T_T);
printf("message_receive.T_Tp2: %" PRIu32 "\n",message_receive.T_Tp2);
time_t total_secs;
int Receive_T=ntohl(message_receive.T_T);
Receive_T = Receive_T - 2208988800L;
total_secs = Receive_T;
printf("Today time is: %s",ctime((const long *)&total_secs));
}

答案 1 :(得分:0)

您正在向NTP服务器发送字符串"Client Originate Timestamp …";这不是NTP Specification中描述的有效NTP数据包。