C/C++ 在網路下的程式設計的應用(時間同步器)
阿新 • • 發佈:2019-01-05
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; }