一、创建一个链接(TCP三次握手)
HTTP是一个基于TCP协议的应用层协议,由请求和响应构成,另外还有HTTPS,是以安全为目标的HTTP通道,是HTTP协议加上SSL协议层的安全加密传输,另外TLS也是SSL的升级(具体关系不详细说,有兴趣的同窗能够百度)git
那么咱们在创建一个链接的时候须要经历3个步骤(三次握手):github
(1)Seq序号(sequence number):占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。编程
(2)确认号(acknowledgement number):Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。跨域
(3)标志位(Flags):共6个,即URG、ACK、PSH、RST、SYN、FIN等。具体含义以下:浏览器
URG:紧急指针(urgent pointer)有效。
ACK:确认序号有效。
PSH:接收方应该尽快将这个报文交给应用层。
RST:重置链接。
SYN:发起一个新链接。
FIN:释放一个链接。缓存
须要注意的是:安全
不要将确认序号Ack与标志位中的ACK搞混了。确认方Ack=发起方Seq+1,两端配对。服务器
三次握手的具体步骤:
创建一个TCP链接时,须要客户端和服务器端总共发送3个包。
三次握手的目的是链接服务器指定端口,创建TCP链接,并同步链接双方的序列号和确认号,交换TCP窗口大小信息。在socket编程中,客户端执行connect()时将触发三次握手。cookie
第一次握手(SYN=1,seq=x):
客户端发送一个TCP的SYN标志位置1的包,指明客户端打算链接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。socket
第二次握手(SYN=1,ACK=1,seq=y,ACKnum=x+1):
服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1。服务器端选择本身的ISN序列号,放在seq域里,同时将确认序号(Acknowledgement Number)设置为客户的ISN加1,即X+1。发送完毕后,服务器端进入SYN_RCVD状态。
第三次握手(ACK=1,seq = x+1 ,ACKnum=y+1):
客户端再次发送确认包(ACK=1),SYN标志位为0,而且把服务器发来ACK的序号字段+1,放在肯定字段中发送给对方,而且在数据段放 X 的+1。
发送完毕后,客户端进入ESTABLISHED状态,当服务器端收到这个包时,也进入ESTABLISHED状态,TCP握手结束,TCP链接创建完成。
2.请求
创建链接以后,咱们就要开始向服务端发起请求
HTTP/1.1协议中,客户端和服务端默认对方支持长链接-keepalive,由于 keepalive 在不少状况下可以重用链接,减小资源消耗,缩短响应时间,因此在 HTTP1.1 中缺省就是支持 keepalive 的。
若是响应方不想支持 keepalive,须要在应答报文头中明确的标识 Connection:close,那么客户端设置的 Connection:keep-alive 就失效了,若是客户端不想支持keepalive,须要在请求报头中明确标识Connection:close
设置 HTTP 短链接:
在应答报文头中设置 Connection:close,则在一次请求/响应以后,就会关闭链接。设置 HTTP 长链接,有过时时间:
在应答报文头中设置 Connection:keep-alive 和 Keep-Alive: timeout=60,代表链接创建以后,空闲时间超过60秒以后,就会失效。若是在空闲第 58 秒时,再次使用此链接,则链接仍然有效,使用完以后,从新计数,空闲 60 秒以后过时。设置 HTTP 长链接,无过时时间:
在应答报文头中只设置 Connection:keep-alive,代表链接永久有效。
http一次请求的过程大概以下:
- 用户在浏览器输入www.xxxxx.com
- dns服务器解析/或者本机hosts,路由器hosts对比 得到ip
- 浏览器访问默认端口80,tls,ssl协议端口443,则访问的tcp地址为 ip:80
- tcp协议3次握手,创建链接
- 发送一个http request请求头
- 服务器得到http request请求头,代表该次访问为http访问,解析http请求头,得到请求类型,请求格式,以及请求数据(cookie,get,post数据)
- 服务器发送response响应数据,主动断开
- 浏览器接收response响应数据,解析响应文本类型,解析数据,断开链接
HTTP请求由三部分组成 : 请求行,消息报头,请求正文
请求行
请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式以下:
Method Request-URI HTTP-Version CRLF
GET /Chris.jpg HTTP/1.1
Method : 请求方法; Request-URI :统一资源标识符; HTTP-Version:请求的HTTP协议版本; CRLF:回车和换行
各类请求方法:
HTTP请求方法也被叫作“请求动做”,不一样的方法规定了不一样的操做指定的资源方式。服务端也会根据不一样的请求方法作不一样的响应。
- OPTIONS:容许客户端查看服务器的性能。这个方法会请求服务器返回该资源所支持的全部 HTTP 请求方法,该方法会用’*’来代替资源名称,向服务器发送 OPTIONS 请求,能够测试服务器功能是否正常。JavaScript 的 XMLHttpRequest 对象进行 CORS 跨域资源共享时,就是使用 OPTIONS 方法发送嗅探请求,以判断是否有对指定资源的访问权限。
- HEAD:与GET方法同样,都是向服务器发出指定资源的请求,可是服务器在响应 HEAD 请求时不会回传资源的内容部分(即响应实体),这样咱们在不传输所有内容的状况下,就能够获取服务器的响应头信息。HEAD方法常被用于客户端查看服务器的性能。
- GET:请求指定的页面信息,并返回响应实体。通常来讲 GET 方法应该只用于数据的读取,而不该当用于会产生反作用的非幂等的操做中。
- POST:向指定资源提交数据,请求服务器进行处理,如:表单数据提交、文件上传等,请求数据包含在请求体中。POST 方法是非幂等的方法,由于这个请求可能会建立新的资源或修改现有资源。
- PUT:向指定资源位置上传其最新内容,PUT 方法是幂等的方法。经过该方法客户端能够将指定资源的最新数据传送给服务器取代指定的资源的内容,经常使用于修改指定资源。
- DELETE:请求服务器删除所请求 URI 所标识的资源。DELETE 请求后指定资源会被删除,DELETE 方法也是幂等的。
- TRACE:请求服务器回显其收到的请求信息,该方法主要用于 HTTP 请求的测试或诊断。
- CONNECT:该方法是 HTTP/1.1 协议预留的,可以将链接改成管道方式的代理服务器。一般用于 SSL 加密服务器的连接与非加密的 HTTP 代理服务器的通讯。
- PATCH:出现的较晚,它在 2010 年的 RFC 5789 标准中被定义。PATCH 请求与 PUT 请求相似,一样用于资源的更新。两者有如下两点不一样:一、PATCH 通常用于资源的部分更新,而 PUT 通常用于资源的总体更新;二、当资源不存在时,PATCH 会建立一个新的资源,而 PUT 只会对已在资源进行更新。
消息报头
HTTP消息报头包括普通报头、请求报头、响应报头、实体报头。每个报头域都是由 名字+:+空格+值 组成,消息报头域的名字不区分大小写。
- 普通报头:普通报头中有少数报头域用于全部的请求和响应信息,但并不用于被传输的实体,只用于传输的消息(如缓存控制,链接控制等),通用头域包含Cache-Control、Connection等等。既能够出如今请求报头,也能够出如今响应报头中
- 请求报头:用于向服务器端传递请求的附加信息 ,请求报头的HTTP报头结构:通用报头-请求报头-实体报头
- 响应报头:用于服务器端传递附加的响应信息 , 响应报头的HTTP报头结构:通用报头-响应报头-实体报头
- 实体报头:实体报头定义了关于实体正文和请求所标识资源的元信息
典型的请求头有:
Host:请求的主机名,容许多个域名同处一个IP地址,即虚拟主机
User-Agent:内容包含发送请求的用户信息,通常是浏览器类型、操做系统等信息
Accept:客户端可识别的内容类型列表,用于指定客户端接收那些类型的信息
Accept-Controller-Allow-Origin :本次请求来自哪一个源,服务器根据该值判断是否赞成请求,在解决跨域问题上也会用到
Cache-Controller:指定请求和响应的缓存机制。只在当前请求生效
Connection:容许客户端和服务器指定与请求/响应链接有关的选项,例如这是为Keep-Alive则表示保持链接。
Cookie:Cookie分2种,一种是客户端向服务端发送的,使用Cookie报头,用来标记。另外一种是服务器发给浏览器的,报头为set-Cookie。
请求正文和响应正文
消息报头结束以后,空行 标志着请求头结束,请求正文(请求体)的开始
username=aa&password=1234
响应正文就是服务器返回的资源的内容,响应头和正文之间也必须用空行分隔
四次挥手
创建一个链接须要三次握手,而终止一个链接要通过四次挥手,这是由TCP的半关闭(half-close)形成的。具体过程以下所示。
- 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP因而发送一个FIN分节,表示数据发送完毕。
- 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。
- 注意:FIN的接收也做为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其余数据以后,由于,FIN的接收意味着接收端应用进程在相应链接上再无额外数据可接收。
- 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这致使它的TCP也发送一个FIN。
- 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。 既然每一个方向都须要一个FIN和一个ACK,所以一般须要4个分节。