日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

3-1:HTTP协议之应用层协议了解

發布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3-1:HTTP协议之应用层协议了解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • (1)協議
    • (2)網絡版“計算器”

網絡分層十分復雜,但是我們開發的大部分網絡程序,均在應用層上運行

(1)協議

OSI分層模型中,每一層都有自己的協議,還是那句話協議是雙方建立的約定,在應用層也是這樣。讀寫數據時,實際上是按照比特位進行接受的,那么對于一些結構化的數據應該怎樣傳輸呢,這樣就需要我們制定出一些協議。這種打包數據和解包數據的過程稱之為序列化和反序列化

  • 序列化:把對象轉為字節序列
  • 反序列化:把字節序列恢復為對象

(2)網絡版“計算器”

根據之前學習過的套接字編程,我們可以編寫一個網絡版的計算器。代碼如下
Server.cpp :服務器接受客戶端的發來的操作數和運算符完成相應的計算

#include "Server.h"int main(int argc,char* argv[]) {if(argc!=2){cout<<"端口號未傳入"<<endl;exit(1);}Server* se=new Server(atoi(argv[1]));se->InitServer();se->StartServer();return 0;}

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

關于這份代碼有以下幾點需要強調

  • 所謂的協議:指的就是對于客戶端和服務端他們都要認為x是左操作數,y是右操作數,并且右操作數在進行某些運算時不能為0;如果出現非法計算,客戶端和服務單都要明白不同狀態碼代表的意思是什么;客戶端發送時發送了一個request,接受時接受了一個response
  • 上述過程其實已經完成了序列化和反序列化,之所以沒有明顯的感覺是因為客戶端發送時發送了一個request,接受時接受了一個response,他們都是非常標準的結構化數據,在發送時是二進制流,但是解包時被當做了標準的結構體解包
  • 這種“序列化后反序列化”的方式是嚴重不推薦的,因為客戶端和服務端可能在完全不同的環境中。實際工作中可以使用正規的序列化工具,如json,xml
  • 代碼效果如下

    總結

    以上是生活随笔為你收集整理的3-1:HTTP协议之应用层协议了解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。