文章目录

  • (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 

关于这份代码有以下几点需要强调

  1. 所谓的协议:指的就是对于客户端和服务端他们都要认为x是左操作数,y是右操作数,并且右操作数在进行某些运算时不能为0;如果出现非法计算,客户端和服务单都要明白不同状态码代表的意思是什么;客户端发送时发送了一个request,接受时接受了一个response
  2. 上述过程其实已经完成了序列化和反序列化,之所以没有明显的感觉是因为客户端发送时发送了一个request,接受时接受了一个response,他们都是非常标准的结构化数据,在发送时是二进制流,但是解包时被当做了标准的结构体解包
  3. 这种“序列化后反序列化”的方式是严重不推荐的,因为客户端和服务端可能在完全不同的环境中。实际工作中可以使用正规的序列化工具,如jsonxml

代码效果如下

3-1:HTTP协议之应用层协议了解相关推荐

  1. 现场解析服务化 即时通讯方案丨网络协议,应用层协议的选择

    90分钟解析服务化 即时通讯方案,(不要错过) 1. 网络协议选择 udp/tcp 2. 应用层协议选择 protobuf/xmpp/mqtt 3. 数据库表的设计 视频讲解如下,点击观看: [Lin ...

  2. 【网络原理】- 传输层 TCP 十大机制 / UDP 协议 自定义应用层协议

    目录 1.自定义应用层协议 1.1 自定义协议,应该如何约定 2.传输层 UDP/TCP 原理 2.1 UDP协议 2.2 传输层 TCP 的十大机制 2.2.1 确认应答 2.2.2 超时重传 2. ...

  3. FTP、TFTP、HTTP、SMTP、DHCP、Telnet、DNS、SNMP(网络协议:应用层协议)

    面试和笔试中,如果记住下面这张图,基本就能解决网络协议中70%的问题.需要记住: OSI模型和TCP/IP模型每一层名称: 每一层对应有哪些协议,或者说给出该协议要知道对应那一层: 该协议是基于TCP ...

  4. 基于TCP或UDP协议的应用层协议

    TCP和UDP都是传输层协议,上面是应用层,下面是网络层 TCP与UDP区别: TCP(传输控制协议)提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连 ...

  5. 36 张图详解应用层协议:网络世界的最强王者

    上帝视角 应用层 我们前面介绍过 TCP/IP 模型的下三层,分别是网络接入层.网络层和传输层.它们都是为应用层服务的,传输应用层的各种数据,现在我们就来看看最高层的应用层. 应用层 在 TCP/IP ...

  6. 网络编程知识预备(4) ——了解应用层的HTTP协议与HTTPS协议

    参考:简单了解HTTP协议与HTTPS协议 作者:丶PURSUING 发布时间: 2021-03-15 10:55:13 网址:https://blog.csdn.net/weixin_4474282 ...

  7. 带你一文看懂--应用层、传输层的协议,HTTP协议及实现,UDP和TCP的报文格式以及为什么3次握手和4次挥手

    网络基础:TCP/IP四层模型中的典型协议--理解网络通信的流程原理 应用层协议:负责应用程序之间的数据沟通 网络版计算器:客户端向服务端传递两个数字以及一个运算符,服务端收到数据进行解析得到数字与运 ...

  8. 应用层协议:HTTPS

    1. HTTPS定义 Hyper Text Transfer Protocol over Secure Socket Layer,安全的超文本传输协议,网景公式设计了SSL(Secure Socket ...

  9. 【计算机网络】2.1 应用层协议原理

    第二章第一节 应用层协议原理 网络应用是计算机网络存在的理由,在本章中,我们学习有关网络应用的原理和实现方面的知识.我们学习包括应用沉香谷所需要的网络服务.客户和服务器.进程和运输层接口. 我们详细考 ...

最新文章

  1. centos6.5下iptables基础知识详解与配置
  2. 【金三银四】java多线程并发编程pdf
  3. 给定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。
  4. 007-SDK框架之LYWSDKInterfaceProtocol.cpp
  5. LinkedHashMap源码剖析
  6. arcgis安装license的问题
  7. 【TypeScript系列教程11】函数的使用
  8. 这一次搞懂 Spring 的 Bean 实例化原理
  9. grub配置文件丢失的解决方法
  10. 机器学习算法_机器学习算法之PCA算法
  11. Asp.net 后台添加Meta标签方法
  12. linux 查看所有存在的线程
  13. Fgui Glist 实现无限滑动 虚拟列表
  14. 人工智能——深度学习
  15. ios 改变图片尺寸_iOS 修改图片尺寸的方法
  16. “pip-script.py”is not present的问题
  17. 东东在用计算机计算一道题时 把被除数的前,北师大二年级数学下册期末试卷...
  18. 硬件:宽带猫(光猫)的基础知识
  19. Dots Entity 删除
  20. Eboot之函数BootloaderMain函数分析

热门文章

  1. 重磅:微信小程序开放公测了!
  2. 深入理解Hadoop之HDFS架构
  3. excel教程自学网_想学习PS和视频剪辑,自学,有哪些好的学习网站和资源吗?
  4. 没有Science也没有娃,上海交大博士谈科研经历爆笑全场
  5. 美图秀秀 Mac版终于上线 关于美图秀秀 Mac版初体验
  6. NOI数据结构:最小树形图
  7. Python将绝对路径转换为相对路径方法实例
  8. android 应用专属目录,获取Android应用专属缓存存储目录的实例
  9. 【分享-windows文件快速搜索神器】Everything 免费、快速搜索文件/文件夹
  10. python用动态规划求删除路径_Python | 动态规划求解TSP