http是应用层的协议, 应用程序之间数据格式的约定统一格式, 由程序员们自己约定
协议可以用自定制协议也可以是已有的、优秀的知名的协议.
http协议就是大佬们弄好的针对典型应用的知名的nb的协议.(应用层的知名的协议还有: http 超文本传输协议,https 解密的http, ftp 文件传输协议, smtp 邮件传输协议, dns 域名解析协议)
自定制协议: 我们可以自己随便定义使用的数据格式, 但是要高效就得考虑: 序列化,反序列化的传输性能和解析性能问题. 序列化后的二进制数据越短传输性能越好, 序列化和反序列化的过程越简单解析性能越好. 通常使用结构体的二进制序列化解析性能非常高 (通过的是结构体的特性,对成员变量的赋值就能实现数据在内存中的序列化.) 但是结构体方式的序列化存在缺陷: 不同平台 位段的使用、字节对齐 不同.
http协议是应用层协议,在传输层用的tcp协议.也就是说http服务器也就是tcp服务器. http协议是个简单的请求-响应协议,一次请求一个响应. http是明文字符串传输协议(2.0版本前), 即协议组织的请求响应数据是人能看得懂的.
http协议的请求格式:
首行:
首行就是请求报文中的第一行, 包含三个要素: method url version\r\n, 三个要素之间用空格间隔.
一个完整的首行就例如:
GET http://www.baidu.com:9090/path?key=val&key=val#ch HTTP/1.1\r\n
(\r\n是换到下一行行首, 不是一个字符串的意思)
method: 请求方法.
请求方法描述了这个请求的目的, 比如是获取数据还是提交数据或者是修改数据, 删除数据. 典型的有:
GET: 获取数据, 也可以提交少量数据, 提交的数据在url中,有安全隐患长度也有限制.
POST: 提交数据, 提交的数据在正文中, 长度无限制.
HEAD: 与GET类似,但响应不要正文数据,只要头部描述.
URL: 统一资源定位符, 俗称网址.
较为完整的URL格式:
协议方案名称://用户名:密码@域名或IP地址:端口/资源路径?查询字符串#片段标识符
协议方案名称: 描述通信所用协议.
用户名:密码 :现在已经很少用了,因为之间把用户名和密码放在网址上是不安全的.
域名或ip地址: 服务器的别名, 方便人记忆的(比如baidu.com), 通过域名解析得到服务器ip地址.
端口: 域名(或ip地址)和端口定位描述了网络中的某一台主机上的某个进程, http默认80端口,https-443端口
/资源路径: 描述客户端只能指定路径下的某个实体资源, / 是服务器里的相对根目录. 域名(或ip地址)+端口+/资源路径,就决定了客户端这个请求的是网络中指定主机上的指定资源, 且这个请求由哪个进程处理.
查询字符串: 客户端提交给服务端的少量数据, 格式为(键值对): key=val&key=val ...
为了防止提交的数据中有特殊字符(字母外的字符)比如? 会造成特殊字符与url中的间隔符产生歧义, 所以特殊字符需要进行转义, 即url编码,urlencode.
urlencode: 遇到特殊字符将其每个字节转换为16进制的数字字符, 比如我们搜索c++在请求报文中的url中的查询字符串中的 ' + ' 就转成ascii表十六进制的2B. 并且转换后为了表示这是特殊字符,加前缀标识%,比如c++转为c%2B%2B
urlencode: url解码,对url编码后的数据解码, 遇到%,则将%后的两个字符的16进制ascii值转换为特殊符号.
片段标识符: html网页中的标签id,加了片段标识符可以让网页直接滑动到指定位置.
version: http协议版本号
协议版本后的 \r\n 就是转到行首,换行,就像回车换行到下一行行首.
0.9版本: 不成成熟的版本, 只有GET的方法,协议格式不完善.
1.0版本: 规范了协议格式, 有了HEAD,POST,GET方法, 支持了多媒体数据流传输.
1.1版本: 支持更多请求方法和头部字段, 有了长连接管理和缓存管理.
2.0版本: 由于http协议臃肿,重新进行了设计,有点推翻重建内维尔, 解决了一些典型,性能的问题.
1.0相较0.9: 主要规范了协议格式, 支持了更多更能和数据传输方式..
1.1相较1.0: 主要在性能上改进.缓存控制: 一些资源在没有改变则不需要重新再次传输.
长连接的改进: 短链接: 一次连接只处理一次请求, 即建立连接,发送请求,得到响应,断开连接. 而下次(每次)请求得再次新建一个链接. 长连接: 一次链接中可以进行多次请求. 长连接相较于短链接节省了大量的来连接建立时间
1.1版本的长连接是管线化思想, 2.0版本的长连接是多路复用思想.
管线化:相较于传统长连接,请求连续发送同时处理,节省处理时间,按序响应
缺陷:响应必须与请求顺序一致,存在队头阻塞问题
队头阻塞:如果第一个资源处理时间长,就算后边的资源准备好了也不能响应
2.0版本中的长连接多路复用: 解决了队头阻塞问题,每个响应中包含对应的请求描述,因此哪个资源准备好了就可以直接响应
2.0相较1.1:
1.从明文字符串传输改为二进制传输
⒉支持服务端主动推送依赖数据(以前是一次请求一次响应),一次请求,可以响应多个数据
3.多路复用在响应头部中添加请求信息,不用按序响应,解决队头阻塞问题
4.保存以前传输中没有出现的头部字段,相同的头部字段不同每次都重新传输了