C/C++ 在网络下的编程的应用(时间同步器)

   写一个基于UDP的时间服务器。
   时间服务器提供的功能就是: 当客户端发送请求时,发回当前的系统时间。时间服务器要写成死循环,用信号退出。

   提示:系统时间找 time() 获得秒差,函数localtime()负责把秒差转成 年月日小时分秒的格式,返回给客户端。localtime()返回时间的结构体指针 struct tm,具体成员 在localtime的手册中可以看到。

简介: 采用UDP方式发送,客户端直接发包即可,但是对于服务器端,首先要先绑定socket,然后就可以接收到来自客户端的信息包了。

           time()是返回的是1970-01-01 00:00:00 +0000 (UTC).到现在的秒数差。

           然后localtime()就是通过计算秒数差来求出现在的时间

服务器端程序代码:

#include                   //  头文件的代码随时添加,通过linux man 命令来查找你所调用函数的作用,然后添加包含这个函数的头文件
#include
#include
#include
#include
#include
#include
#include
#include
int fd;
void fa(int sing){                
  printf("receive the Ctrl + c and try to exit the application\n");
  int i = 0;
	printf("Exiting");
	fflush(stdout);
	for(i = 0;i < 5; ++i){
	  printf(".");
		fflush(stdout);

		sleep(1);
	}
	printf("\n");
	close(fd);
	printf("exit successfully\n");
	exit(0);
}

int main(void){
  printf("Ctrl + c to exit the application\n");
	signal(SIGINT,fa);           // 发送Ctrl + c 就会使程序调用自己定义的fa函数,然后使程序自动推出。
	fd = socket(PF_INET,SOCK_DGRAM,0);                  // 产生socket变量, 采用的是PF_INET 网络通信,SOCK_DGRAM UDP传输方式,0 无意义
	if(fd == -1)perror("s_socket"),exit(EXIT_FAILURE);
  struct sockaddr_in addr;                                  //定义数据类型为sockadd_in 的变量,然后
	addr.sin_family = PF_INET;                          // 和socket第一个参数相同
	addr.sin_port = htons(2222);                        // 定义开辟的通讯的端口号的地址 注意因为计算机内部会从高到地 或 低到高 位置 存储数据,所以
	addr.sin_addr.s_addr = inet_addr("192.168.0.209");  // 需要htons来转换端口号  通信地址是字符ip地址
	int res = bind(fd,(struct sockaddr*)&addr,sizeof(addr));    // 绑定socket 
  if(res == -1)perror("s_bind"),exit(EXIT_FAILURE);
	while(1){
		char buf[150]={};
		socklen_t len = sizeof(addr);
		recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&addr,&len);       // 接收数据
		printf("you receive the message from %s\n",inet_ntoa(addr.sin_addr));
		printf("the content is %s\n",buf);
  	if(!strcmp(buf,"time")){
	  	 sendto(fd,"happy",5,0,(struct sockaddr*)&addr,sizeof(addr));      //发送数据
     	 printf("successful\n");
		 	 time_t t;                                                 // 处理时间
		   time(&t);
		   struct tm *tt = localtime(&t);
		   sendto(fd,tt,sizeof(struct tm),0,(struct sockaddr*)&addr,sizeof(addr));
	  
		}else {
	  	 sendto(fd,"fail",4,0,(struct sockaddr*)&addr,sizeof(addr));
			 printf("the connecter's message is fault\n");
		}	
	}
	return 0;
}

客户端程序的代码:   客户端和服务器端类似 只是不存在了绑定
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
int main(void){
  int fd = socket(PF_INET,SOCK_DGRAM,0);
  if(fd == -1)perror("s_socket"),exit(EXIT_FAILURE);
	struct sockaddr_in addr;
	addr.sin_family = PF_INET;
	addr.sin_port = htons(2222);
  addr.sin_addr.s_addr = inet_addr("192.168.0.136");
	//int res = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
	//if(res == -1)perror("s_bind"),exit(EXIT_FAILURE);
  char buf[150] = {"time"};
	sendto(fd,buf,sizeof(buf)+1,0,(struct sockaddr*)&addr,sizeof(addr));
  read(fd,buf,sizeof(buf));
	printf("%s\n",buf);
	struct tm *t =  (struct tm*)malloc(sizeof(struct tm));  //这里需要动态开辟存储空间,否则会一直报段错误
	if(!strcmp(buf,"happy")){
		 int judge = read(fd,t,sizeof(struct tm));
		 printf("%d/%d/%d %d:%d\n",
		 t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min);
	}
	close(fd);
	return 0;
}
C/C++ 在网络下的编程的应用(时间同步器)_第1张图片

你可能感兴趣的:(linux,网络编程,c++学习)