目录
应用层:负责应用程序之间的数据沟通
一、自定制协议(私有协议)
二、HTTP协议
1)、请求行解析:GET /index.html HTTP/1.1
第一部分:请求方法:多种多样,描述不同的请求目的
第二部分:URL
第三部分:协议版本
2)请求头部
3)空行
4)正文:
5)响应行
三、Cookie 与 Session
四、HTTPS协议
应用层:负责应用程序之间的数据沟通
应用层协议其实是面向程序员的协议,因为应用程序是程序员自己写的,因此引用程序之间如何沟通是程序员定的
程序员自己订立的程序沟通的数据格式约定,而针对某些场景,大佬们定制出的协议,大家觉得非常好,都用了这种协议,这种协议叫做知名协议(很有名)
一、自定制协议(私有协议)
程序员自己定义的程序沟通的数据格式约定完成序列化与反序列化的一种标准
序列化:在网络传输或者数据的持久化存储时,将多个数据对象按照指定格式组织成为一个二进制数据进行传输或持久化的过程
反序列化:对二进制数据传,按照指定格式进行解析,得到各个数据对象的过程
程序员设计自定制协议时需要考虑哪些问题呢?
① 传输性能 定制一个协议,传输时的数据尽可能的短小,传输数据的时候才能尽可能的快
② 解析性能 传输多个数据对象的时候需要序列化,对方拿到数据后要进行反序列化,解析性能指的就是序列化和反序列化要足够快
③ 调试便捷性:讨论的更多的是对于程序员的可见性。可识别性
实例:网络计算器
一个客户端进行俩个数据的运算,运算的过程并不是自己执行,而是将数据传输给服务器,让服务器运算、并返回结构
数学运算: 11 + 22
需要向服务器传输的数据对象有三个:第一个数字、第二个数字、运算符
协议如何定制:
方案一: 11 + 22字符串传输, 解析过程:获取数字字符,遇到其他字符截止,取出第一个数字,特殊字符为运算符,剩下的获取数字字符
方案二:11;22;+; 逆波兰表达式,进行字符串分割,前俩个字符串转化为数字,最后为运算符
方案三:二进制序列化:将三个对象的二级制数据分别放到一整块内存的指定位置,最终按照位置进程解析即可
二、HTTP协议
互联网公司中使用最多的协议
认识:HTTP——超文本传输协议(最早期就是为了传输web网页而设计的)
特性:1、基于字符串明文传输的,调试便捷性高
2、是一种简单的请求-响应协议(早期是短链接--一次请求-响应结束就关闭)
3、基于TCP协议,传输安全可靠
书写一个简单的TCP访问,使用tcp响应发送以下内容
std::cout<<"client say:["<<buf<<"]"<<std::endl; std::string body = "<html><body><h1>Hello wxl</h1><body></html>"; buf.clear(); buf = "HTTP/1.1 200 OK\r\n"; buf += "Content-Length: "; buf += std::to_string(body.size()); buf += "\r\n\r\n"; buf += body; new_sock->Send(buf);
通过云服务器端口进行访问
格式:看下面这个数据传输示例
GET 为方法; /index.htm 请求URI; HTTP/1.1即为版本号
请求报文是由(请求行(首行)、请求头部、空行、正文)
请求与响应报文模型
一层一层剖析:
1)、请求行解析:GET /index.html HTTP/1.1
请求行中的内容分为三部分,以空格作为间隔,请求行以 \r\n结尾 (刚好就是一行数据)
第一部分:请求方法:多种多样,描述不同的请求目的
GET:向服务器请求一个网页实体资源,请求中没有正文,但是也可以向服务器提交数据,提交的数据在URL中(安全性低,长度受限)
POST:向服务器提交表单数据,请求中有正文
HEAD:面试中经常会问到GET与HEAD的区别——目的与GET类似,但不同的是,实际的响应中不要实体资源,只要响应头部
使用fiddler抓包工具彻底搞懂Get与Host区别及使用http://t.csdn.cn/cHv3u
PUT:更新服务器上的资源
DELETE:删除服务器上的资源
……
第二部分:URL
URL:统一资源定位符,其实就是咱们所说的网址,功能就是定位网络上某一台主机上的某个资源
完整格式: http://username:password@domainname:port/s?wd=C%2B%2B#ch
特殊符号为间隔符(:// : @ : ? #)
http:协议方案内容,当前大多都是https(对http协议的加密)
username:用户名; password:密码
domainname:域名或者服务器IP地址 即就是(baidu.com 或者 14.215.177.39)
域名:IP地址才是网络上一台主机的唯一标识,但是IP地址不容易记忆,因此大佬们就设计了域名系统,使用便于记忆的字符串作为域名,通过域名上网时,先通过域名系统进行域名解析,得到服务器的IP地址,然后通过iP地址进行访问
ping是一个十分基本但又十分重要的TCP/IP网络工具。它的作用主要为:
(1)通常用来检测网络的连通情况和测试网络速度;
(2)也可以根据域名得到相应主机的IP地址;
(3)根据ping返回的TTL值来判断对方所使用的操作系统及数据包经过路由器数量。
(4)因为具备以上功能,ping命令常常被黑客用来进行网络扫描和攻击。
port:很多时候我们浏览网页,在网址中并没有看到端口,这是因为HTTP服务默认使用80端口,浏览器自动加上啦(HTTP 80端口, https443端口 ssh 22 端口)
加上:443 进入百度网页
输入其他端口就会无法访问
/s: 资源路径,以/作为起始, 明确的描述要请求的资源路径名。 / 表示根目录,但是实际上只是服务器上的相对子目录
左侧是给予客户端访问的相对路径: 右侧实际是服务端的文件存储位置
/index.html --》 /home/dev/workspace/proiect/bit-http-v2/src/http/wwwroot/index.html
因为服务端不能把自己所有的文件权限都交给你,让你都能访问,这是不合理的,所以服务端给你一个相对地址,你只能访问这个相对地址以下目录内容文件,不能访问该层往上文件目录
不能让用户随意的访问服务器上的文件,只能访问相对根目录中的所有文件
wd=C%2B%2B&encode=utf8: GET 请求提交给服务端的数据,学名叫做查询字符串
查询字符串中的数据,是提交给服务器的数据,放在URL中,但是URL中很多特殊字符都是特殊含义的,但是提交的数据中也有了中特殊字符,就会造成二义性。因此,标准文档规定了,查询字符串中的特殊字符要进行编码(URL编码)
URLEncode:URL编码,对特殊字符进行转义,将特殊字符数据转为16进制的ASCII前缀%
+ -》 %2b +的ascii为43, 16进制就是2b
URLDecode:URL解码,在URL中遇到了%字符,则认为其后的俩个字符进行了url编码需要解码
%2b -》 2*16+11 -> 43 -》 +
ch: #之后的数据,叫做片段标识符,通常用于定位网页中的某个标签id,用于打开网页后,直接跳转到指定位置
第三部分:协议版本
描述了当前请求所使用的HTTP协议版本,不同的版本之间有功能支持力度上的差异
HTTP协议的版本迭代:HTTP/0.90.9版本,是一个不成熟的版本,只能使用GET获取网页,而且也没有当前的完善的协议格式
HTTP/1.01.0版本,完善了协议格式,新增支持了更多的请求方法:GET, HEAD,POST,并且有了缓存的控制,以及流媒体的传输
HTTP/1.11.1版本,是当前用的最多的版本,新增支持了更多的请求方法: PUT,DELETE ....针对当前的网络,觉得以前的通信效率太低了: 支持了长连接, 对缓存的管理更加精细了
长连接与短连接
长连接旨在只通过进行一次TCP连接后可以进行多次的请求与响应的交互
减少了TCP连接的重复建立和断开造成的额外开销,减轻了服务器的负载
长连接管线化传输(使得TCP建立一次连接后,可以同时并行发送多个请求,不需要一个接一个等待响应)
HTTP/1.1版本的迭代,更多的是对传输效率的改进
HTTP/2 这个版本是一个大跃进,因为并不向前兼容1.使用二进制传输,以前是名文字符串2.不用重复每次请求传输相同的头部字段3.长连接的一些改进,不需要按序响应,解决了队头阳塞问题4.主动推送功能的加入, 服务器响应数据的时候,可以主动响应依赖数据
2)请求头部
由一个一个的键值对组成(针对请求的一些附加描述,以及对于请求正文的描述)
请求头部
User-Agent(用户代理),Host(域名),Referer(当前网页的来源)
例如,在
www.google.com
里有一个www.baidu.com
链接,那么点击这个www.baidu.com
,它的header 信息里就有:Referer=http://www.google.com
正文头部(在请求与响应中都会出现,主要是对于正文的描述)
Content-Length:129 用于描述正文长度
Content-Type:application/json;charset=UTF-8
用于描述正文的数据类型(决定了如何解析正文)
响应头部(只会在响应中出现的头部字段,描述响应)
Location:http://baidu.com 用于描述重定向
通用头部(在请求与响应中都会出现,属于对于本次通信或连接的一些描述)
Connection:keep-alive/close:用于描述当前的连接使用的是短连接还是长连接
3)空行
\r\n 主要用于间隔HTTP头部与正文
主要是在实现解析时,先接受一个完整的HTTP协议头部,根据其中的Connect-Length确定正文长度,然后根据正文长度取出指定长度的正文,则刚好能够完整的获取到一条HTTP请求
4)正文:
提交给服务器的数据,类型格式通过Connect-Type描述
响应格式
响应行,响应头部,空行,正文
5)响应行
协议版本 状态码 状态码描述\r\n HTTP/1.1 200 OK\r\n
状态码:用于明确直接的向客户端表示本次请求的处理结果
1xx:继续请求或者协议切换 101--协议切换
2xx:请求已经成功处理 200--成功处理, 206--区间内容处理成功
3xx:请求重定向 301--永久重定向 302--临时重定向 303--see other 304--not modify
重定向: 把一个请求,重定向到其他链接。示例: 一个请求,要请求的资源,被移动到了其他位置。但是想要依然保持原链接有效
对于301永久重定向来说,当用户访问该网址后,在解析的响应行中含有301这个状态码,则将会在接下来的响应报头中解析Location关键字所对应信息,来告诉用户,我这个旧网址以后就不要访问,以后就访问我这个Location后面这个新的吧!
永久重定向适用于网站迁移、域名更换
对于302临时重定向来说,比如用户在提交购物车的订单之后,系统提示:即将为您跳转到XXX页面进行下一步信息确认……这样的称为临时重定向。
301、302、303这种要跟Location响应头字段搭配使用,Location字段用于指定的重定向的新链接; Location: http://baidu.com
4xx:表示客户端的错误; 400--bad request 404--Not Found 请求资源不存在
5xx:表示服务器的错误, 500--服务器内部错误;
502--bad gateway,代理服务器连接错误
504-gateway timeout--代理请求超时
状态码:没有实际的功能性意义,给程序员看的,一个对于状态码的文字描述信息
响应头部:Connection、Location……
空行:间隔头部与正文
正文:响应给客户端的数据
三、Cookie 与 Session
对于HTTP协议,本身就是一种不保存状态、即无状态(stateless)协议,HTTP协议自身不对请求与响应之间的通信状态进行保存,协议对于发送过的请求或响应都不做持久化处理
无状态协议不需要服务端每次对客户端的信息进行收集与存储,那么对于服务端来说,这无疑减轻了服务端CPU及内存资源的消耗,可以更快的处理大量事物,确保协议的伸缩性,所以这种简单的协议模式更符合我们对于网页的通信需求,被应用于各种场景
那么也就是说我们在登录一个网站输入账号密码之后,刷新一下页面,还需要进行重新输入账号密码,这显然增加了大量的麻烦,那么可不可以有一种机制来帮助我们来存储这种状态信息呢?
Cookie:小饼干,cookie是一种信息缓存机制,将一些信息保存到客户端主机上,等下一次请求服务器的时候读取出来发送给服务器
有了Cookie机制,就可以很好地在多次通信中不断维护客户端的状态,但是这存在缺陷:不安全
session会话,就是在客户端与服务端的通信建立一个会话,将会话重要内容保存起来,会话内容
被保存在服务器上,通过Cookie只需要传递Session_id即可
这样做有个好处,不会再网络上传输用户的敏感信息
session会话机制,在Cookie的基础上,避免了敏感信息的传输,提高了安全性
Cookie与session的区别:
1、Cookie是将信息保存在客户端上,每次通信将之前确认过得Cookie信息绑定一起发送过去
2、session是将会话信息保存在服务端上,通过session_id进行Cookie传输,保护隐私性
四、HTTPS协议
在HTTP协议的基础上进行了一次加密,因此HTTPS不是一个新的协议,而是一个加密的HTTP协议
加密:SSL/TLS加密
为什么要加密:
身份验证:
第三方权威机构 + CA认证