应用层介绍
应用层是什么
我们在之前的文章里讲过,应用层是应用在各个程序之间的数据沟通,其实应用层协议是面向程序员的,因为这些协议都是程序员写的,是方便程序员在编写程序时完成各个应用程序之间的沟通
组织方式
序列化
在网络传输或者数据的持久化储存的时候,将多个数据对象按照指定格式进行组织成一个二进制数据进行传输或者持久性的过程
反序列化
对二进制数据按照指定格式进行解析得到各个数据对象的过程
进行自定制协议主要要考虑的要素:
1.传输性能: 定制一个协议,传输数据要尽可能的快,数据要尽可能的短小,比如我要告诉你我要去吃饭,如果发送一个字符串,传输性能会很差,如果我使用1代表这句话,我们就只需要传输1就可以代表这句话。
2.解析性能: 传输多个数据对象的时候要进行序列化,对方拿到数据之后也要进行反序化,所以解析性能就是序列化和反序列化所消耗的时间 以上会在解析的情况下很慢,传输多个对象的时候要进行数据传输
3.调试便捷性: 更多的是对于程序员的可见性,比如我在编写的时候出错方便调试
常见的自定义序列化方式
1.使用字符串进行组织
2.使用二进制进行序列化,将三个对象的二进制数据分别放到一整块内存的指定位置,最后按照指定的位置进行解析,常用的有结构体序列化,在结构体定义的时候是空间的开辟过程,在结构体中赋值的过程,就是数据组织的过程,所以结构序列化的解析性能是非常高的
在字符串序列化过程中是可见的,使用二进制序列化的话是在内部完成。不同的序列化有不同的优点,传输性能和解析性能侧重点不同,利用领域也不同,比较典型的序列化方式有: json序列化,protobuf序列化,二进制结构体序列化…
举例
网络计算器:例如, 我们需要实现一个服务器版的加法器. 我们需要客户端把要计算的两个加数发过去, 然后由服务器进行计算, 最后再把结果返回给客户端.一般情况下,接收信息和计算不会放到同一个服务器中,可能会发生数据丢失,一般情况下会再给一个计算服务器专门进行运算
约定方式一:二进制结构体序列化演示:
结构体的定义:
struct cal_t { intt num1;//数据1 int num2;//数据2 char op;//计算方式 }
数据的发送:
(以下代码部分是更具之前的博客tcp那一章封装的)
while(1){ struct cal_t cal; cal.num1 = 11; cal.num2 = 22; cal.op = '+'; int fd = cli_sock.fd(); send(fd,&cal,sizeof(cal),0); int res; recv(fd,&res,4,0); std::cout << "res:"<<res<<std::endl; }
数据的接收过程:
std::cout << "new client: "<<cli_ip<<":"cli_port<<std::endl; while(1){ struct cal_t cal; int fd = new_sock,fd(); recv(fd,&cal,sizeof(cal),0); int res = -1; switch(cal.op){ casse '+': res = cal.num1+cal.num2; break; default: break; } send(fd&res,sizrof(res),0); new_sock.close(); }
约束方式二:
客户端发送一个形如"1+1"的字符串;
这个字符串中有两个操作数, 都是整形;
两个数字之间会有一个字符是运算符, 运算符只能是 + ;
数字和运算符之间没有空格;
…
在我+们网络传输的过程中,只要是内存中的数据都可以进行传输,不关心数据的组织方式是怎么样的。因为网络传输是主机传输,所以我们需要考虑以下问题:
1.结构体内存对齐,两端主机采用同样的对齐方式
2.传输的过程字节序的问题,所以要将数据转化为网络字节序进行传输
HTTP协议——超文本传输协议(最早就是用来传输web网页传输的)
HTTP协议的特性
1.是基于tcp协议的,传输可靠安全
2.是基于字符串明文传输,调试便捷性高
3.是一种简单的请求—响应协议(早起是断链接,一次请求响应后关闭)
HTTP协议的格式:
请求行(首行):请求中的第一行,主要对请求进行关键性描述
请求头部:都是一个个的键值对,是对请求的附加描述以及对正文的描述,每个属性以\n进行分隔
空行:间隔头部与正文
正文:提交给服务器的数据
HTTP 请求
请求行
请求行中的内容分为三个部分,以空格间隔,请求行以\r\n作为结尾(请求行一般就是刚好一行数据)
第一部分:请求方法
GET:向服务器请求一个网页实体资源,是没有正文的,也可以向服务器提交数据,提交的数据在url中的,获得的url长度有限,有些是1kb,4kb,8kb,每个地方不一样
POST:向服务器提交表单数据,请求中有正文
HEAD:(在面试中经常会问GET和HEAD有什么区别,作用于GET类似,但不同的是,实际上HEAD要的是头部描述,不要实体资源)
PUT:更新服务器的资源
DELETE:删除服务器上的资源