3-1:HTTP协议之应用层协议了解
生活随笔
收集整理的這篇文章主要介紹了
3-1:HTTP协议之应用层协议了解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- (1)協議
- (2)網絡版“計算器”
網絡分層十分復雜,但是我們開發的大部分網絡程序,均在應用層上運行
(1)協議
OSI分層模型中,每一層都有自己的協議,還是那句話協議是雙方建立的約定,在應用層也是這樣。讀寫數據時,實際上是按照比特位進行接受的,那么對于一些結構化的數據應該怎樣傳輸呢,這樣就需要我們制定出一些協議。這種打包數據和解包數據的過程稱之為序列化和反序列化
- 序列化:把對象轉為字節序列
- 反序列化:把字節序列恢復為對象
(2)網絡版“計算器”
根據之前學習過的套接字編程,我們可以編寫一個網絡版的計算器。代碼如下
Server.cpp :服務器接受客戶端的發來的操作數和運算符完成相應的計算
Server.h
#include <iostream> #include <signal.h> #include <string> #include <unistd.h> #include <cstdio> #include <cstring> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include "protocol.h" using namespace std;class Server { private:int _port;int _listen_socket; public:Server(int port):_port(port){}void InitServer(){signal(SIGCHLD,SIG_IGN);_listen_socket=socket(AF_INET,SOCK_STREAM,0);if(_listen_socket < 0){cout<<"socket creat faile"<<endl;exit(2);}struct sockaddr_in local;local.sin_family=AF_INET;local.sin_port=htons(_port);local.sin_addr.s_addr=INADDR_ANY;if(bind(_listen_socket,(struct sockaddr*)&local,sizeof(local)) < 0){cout<<"socket bind faile"<<endl;exit(3);}if(listen(_listen_socket,5) < 0){cout<<"listen fail"<<endl;exit(4);}}void Service(int sock){//服務器執行計算request_t rq;response_t rp={4,0};//默認狀態碼從4開始ssize_t s=recv(sock,&rq,sizeof(rq),0);//接受客戶端發來的計算要求 if(s > 0){ switch(rq.op)//判斷是什么操作數{case '+':rp.result=rq.x+rq.y;break;case '-':rp.result=rq.x-rq.y;break;case '*':rp.result=rq.x*rq.y;break;case '/':if(rq.y!=0){rp.result=rq.x/rq.y;}else {rp.code=1;//狀態碼為1表示除數為0}break;case '%':if(rq.y!=0){rp.result=rq.x%rq.y;}else {rp.code=2;//狀態碼為2表示%運算時除數為0}default:rp.code=3;//狀態碼為3表示運算符輸入錯誤}}send(sock,&rp,sizeof(rp),0);//把結果發給客戶端close(sock);}void StartServer(){struct sockaddr_in peer;while(1){socklen_t len=sizeof(peer);int sock=accept(_listen_socket,(struct sockaddr*)&peer,&len);if(sock < 0){cout<<"accept faile"<<endl;continue;}pid_t id=fork();if(id == 0){close(_listen_socket);Service(sock);exit(0);}close(sock);}}~Server(){close(_listen_socket);} };Client.cpp:客戶端將數據發送給服務端
#include "Client.h"int main(int argc,char* argv[]) {if(argc!=3){cout<<"請完整輸入ip地址和端口號"<<endl;exit(1);}Client* cp=new Client(argv[1],atoi(argv[2]));cp->InitClient();cp->StartClient();return 0; }Client.h
#include <iostream> #include <signal.h> #include <string> #include <unistd.h> #include <cstdio> #include <cstring> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include "protocol.h" using namespace std;class Client { private:int _port;string _ip;//服務器ip地址int _socket;public:Client(string ip,int port):_ip(ip),_port(port){}void InitClient(){signal(SIGCHLD,SIG_IGN);_socket=socket(AF_INET,SOCK_STREAM,0);if(_socket < 0){cout<<"socket creat faile"<<endl;exit(2);}}void StartClient(){struct sockaddr_in server;server.sin_family=AF_INET;server.sin_port=htons(_port);server.sin_addr.s_addr=inet_addr(_ip.c_str());if(connect(_socket,(struct sockaddr*)&server,sizeof(server)) < 0){cout<<"connected fail"<<endl;exit(2);}request_t rq;//客戶端接收用戶輸入cout<<"請輸入左操作數:"<<endl;cin>>rq.x;cout<<"請輸入右操作數:"<<endl;cin>>rq.y;cout<<"請輸入運算符:"<<endl;cin>>rq.op;send(_socket,&rq,sizeof(rq),0);response_t rp;//接收結果recv(_socket,&rp,sizeof(rp),0);cout<<"狀態碼為:"<<rp.code<<endl;cout<<"結果為:"<<rp.result<<endl;}~Client(){close(_socket);} };Protocol.h:服務端和客戶端都必須遵從的計算協議
#ifndef _PROTOCOL_H #define _PROTOCOL_H #include <iostream>typedef struct request {int x;//操作數1int y;//操作數2char op;//運算符}request_t;typedef struct response {int code;//返回狀態,有可能計算失敗int result;//計算結果 }response_t; #endif關于這份代碼有以下幾點需要強調
代碼效果如下
總結
以上是生活随笔為你收集整理的3-1:HTTP协议之应用层协议了解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3-3:HTTP协议之request和r
- 下一篇: 【README3】动态规划之“找零钱”说