自定協議實現網路計算器
阿新 • • 發佈:2018-11-01
這裡我們的自定執行協議和TCP、UDP、IP這些協議不同,我們自定製的協議是應用層的協議。是我們這兩個應用所應用的一種特殊傳輸和接受資料的方式,這裡我們是通過結構體來儲存資料的,也可以定義一個字串,當我們的資料傳送過去之後,只有我對應的服務端或者客戶端明白我這裡是在幹什麼,如何把這一大塊資料進行劃分。
//這是一個通過自定製協議來實現的網路計算器 //客戶端傳輸過來的資料是提前協定好的 //服務端進行解析之後得到結果返回客戶端 //1.建立socket socket //2.繫結地址 bind //3.開始監聽 listen //4.接受收客戶端連結 accept //5.接受客戶端的資料 //6.以指定的協議來對資料進行解析 //7.進行計算 //8.返回結果 //9.關閉socket #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<errno.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> //我們自己設定協議格式 //前四個自己是一個數字 //之後四個位元組是另一個數字 //最後一個位元組是運算子 typedef struct _cal_req_t { int x; int y; unsigned char sym; }cal_req_t; int main(int argc,char* argv[]) { if(argc!=3) { printf("please input ip/port\n"); return -1; } struct sockaddr_in lst_addr; struct sockaddr_in cli_addr; int lst_fd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(lst_fd<0) { perror("socket error\n"); return -1; } lst_addr.sin_family=AF_INET; lst_addr.sin_port=htons(atoi(argv[2])); lst_addr.sin_addr.s_addr=inet_addr(argv[1]); socklen_t len=sizeof(struct sockaddr_in); int ret=bind(lst_fd,(struct sockaddr*)&lst_addr,len); if(ret<0) { perror("bind error\n"); return -1; } if(listen(lst_fd,5)<0) { perror("listen error\n"); return -1; } while(1) { int new_fd=accept(lst_fd,(struct sockaddr*)&cli_addr,&len); if(new_fd<0) { perror("accept error\n"); continue; } //接受我們特定格式的資料然後開始解析 cal_req_t req; char buff[1024]={0}; ssize_t rlen=recv(new_fd,(void*)&req,1024,0); if(rlen<0) { perror("recv error\n"); close(new_fd); continue; }else if(rlen==0) { printf("shutdown\n"); close(new_fd); } int sum=0; if(req.sym=='+') { sum=req.x+req.y; } if(req.sym=='-') { sum=req.x-req.y; } if(req.sym=='*') { sum=req.x*req.y; } if(req.sym=='/') { sum=req.x/req.y; } send(new_fd,(void*)&sum,4,0); close(new_fd); } return 0; }
//這是網路計算器的客戶端我們給服務端兩個資料一個操作符 //之後接受服務端返回給我們資料並且輸出 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<errno.h> #include<netinet/in.h> #include<sys/socket.h> #include<arpa/inet.h> typedef struct cal_req_t { int x; int y; unsigned char sym; }cal_req_t; int main(int argc,char* argv[]) { if(argc!=3) { printf("please input ip/port\n"); return -1; } int sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(sockfd<0) { perror("socket error\n"); return -1; } struct sockaddr_in addr; addr.sin_family=AF_INET; addr.sin_port=htons(atoi(argv[2])); addr.sin_addr.s_addr=inet_addr(argv[1]); socklen_t len=sizeof(struct sockaddr_in); int ret=connect(sockfd,(struct sockaddr*)&addr,len); if(ret<0) { perror("connect error\n"); return -1; } struct cal_req_t req; printf("請輸入第一個數字\n"); scanf("%d",&req.x); printf("請輸入第二個數字\n"); scanf("%d",&req.y); printf("請輸入運算子\n"); scanf("%s",&req.sym); send(sockfd,(void*)&req,sizeof(req),0); int sum=0; recv(sockfd,(void*)&sum,4,0); printf("%d%c%d=%d\n",req.x,req.sym,req.y,sum); close(sockfd); return 0; }