所以我创建了一个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;
}
非常感谢任何帮助。
答案 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数据包。