HTTP 协议简介
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
请求响应模型
主要特点
支持客户/服务器模式。
简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
灵活:HTTP允许传输任意类型的数据对象,通过Content-Type 标记传输的数据类型。
-
无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
早期这么做的原因是 HTTP 协议产生于互联网,因此服务器需要处理同时面向全世界数十万、上百万客户端的网页访问,但每个客户端(即浏览器)与服务器之间交换数据的间歇性较大(即传输具有突发性、瞬时性),并且网页浏览的联想性、发散性导致两次传送的数据关联性很低,大部分通道实际上会很空闲、无端占用资源。因此 HTTP 的设计者有意利用这种特点将协议设计为请求时建连接、请求完释放连接,以尽快将资源释放出来服务其他客户端。
随着时间的推移,网页变得越来越复杂,里面可能嵌入了很多图片,这时候每次访问图片都需要建立一次 TCP 连接就显得很低效。后来,Keep-Alive 被提出用来解决这效率低的问题。
Keep-Alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive 功能避免了建立或者重新建立连接。(对于提供静态内容的网站来说,这个功能通常很有用。但是,对于负担较重的网站来说,这里存在另外一个问题:虽然为客户保留打开的连接有一定的好处,但它同样影响了性能,因为在处理暂停期间,本来可以释放的资源仍旧被占用。当Web服务器和应用服务器在同一台机器上运行时,Keep-Alive 功能对资源利用的影响尤其突出。 )
-
无状态:是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是,发送完,不会记录任何信息。
于是,两种用于保持 HTTP 连接状态的技术就应运而生了,一个是 Cookie,而另一个则是 Session。
HTTP请求响应头(常规)
-
请求
host: 客户端访问的服务器主机地址。
Method:请求方法
User-Agent:客户端类型、客户端的软件环境
Accept:客户端所能接收的数据类型
Accept-Language: 客户端的语言环境
Accept-Encoding: 客户端支持的数据压缩格式
-
响应
Server: 服务器的类型
Status: 响应状态码
Content-Type:返回数据的类型
Content-Length: 返回的数据长度
Date:响应的时间
HTTP的3次握手和4次挥手
由于HTTP是基于TCP之上的协议,所以这里先了解一些字段标识。
在TCP 层,有个FLAGS字段,这个字段有以下几个标识:
- SYN: 表示建立连接。
- FIN:表示关闭连接。
- ACK:表示响应。
- PSH:表示有DATA数据传输。当发送端将PSH置为1时,TCP会立即创建一个报文并发送,接受端收到PSH为1的报文后就立即将接受缓冲区内数据向上交付给应用程序,而不是等待缓冲区满后再交付。
- RST:表示连接重置。
- URG:紧急标识位。
- seq (sequence number): 表示的是我方(发送方)这边,这个packet的数据部分的第一位应该在整个data stream中所在的位置。(注意这里使用的是“应该”。因为对于没有数据的传输,如ACK,虽然它有一个seq,但是这次传输在整个data stream中是不占位置的。所以下一个实际有数据的传输,会依旧从上一次发送ACK的数据包的seq开始)。
- ack(acknowledge number):表示的是期望的对方(接收方)的下一次sequence number是多少。
日常分析有用的就是前五个。其中ACK可与SYN,FIN同时使用。
3次握手
(1):Client发送SYN=1,随机产生seq number=x的数据包到服务器,Server有SYN=1知道需要建立连接;
(2):Server收到请求后需要确认连接信息,向Client 发送ack number =x+1 (client的seq+1),SYN=1,ACK=1,随机产生seq=y的包。
(3):Client收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,Client会再发送ack number=y+1(Server的seq+1),ACK=1,Server收到确认seq值和ACK=1则建立连接。
此时,Client向Server发出确认后,Client的TCP通知上层应用进程,连接已建立。Server收到Client的确认后,也通知上层,TCP已连接。后面就可以进行数据传输了。
4次挥手
(1):Client发出释放连接的请求,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
(2):Server收到连接释放报文,发出确认报文,ACK=1,ack=z+1,并且带上自己的序列号seq=v,此时,Server端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,Client端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
(3):Client端收到服务器的确认请求后,此时,Client端就进入FIN-WAIT-2(终止等待2)状态,等待Server发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。Server将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=z+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
(4):客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。