1. 程式人生 > >C/C++ 在網路下的程式設計的應用(時間同步器)

C/C++ 在網路下的程式設計的應用(時間同步器)

https://blog.csdn.net/worldmakewayfordream/article/details/24187833

  寫一個基於UDP的時間伺服器。
   時間伺服器提供的功能就是: 當客戶端傳送請求時,發回當前的系統時間。時間伺服器要寫成死迴圈,用訊號退出。
   提示:系統時間找 time() 獲得秒差,函式localtime()負責把秒差轉成 年月日小時分秒的格式,返回給客戶端。localtime()返回時間的結構體指標 struct tm,具體成員 在localtime的手冊中可以看到。

簡介: 採用UDP方式傳送,客戶端直接發包即可,但是對於伺服器端,首先要先繫結socket,然後就可以接收到來自客戶端的資訊包了。

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

           然後localtime()就是通過計算秒數差來求出現在的時間

伺服器端程式程式碼:
 

#include<stdio.h>                   //  標頭檔案的程式碼隨時新增,通過linux man 命令來查詢你所呼叫函式的作用,然後新增包含這個函式的標頭檔案
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<time.h>
#include<signal.h>
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
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;
}