体系结构分层原因:
不同层的协议:
HTTP协议:超文本传输协议,web的应用层协议,是web的核心协议。
HTTP协议使用TCP作为它的支撑运输协议,是一个无状态的协议,不保存客户的任何信息。
http协议可以分为非持续连接协议和持续连接协议。
非持续连接:每个请求/响应对是经一个单独的TCP连接发送
持续连接:所有请求/响应对是经相同的TCP连接发送
HTTP默认使用持续连接
1. HTTP请求方法
HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的HTTP服务器支持扩展自定义的方法。
2. GET和POST的区别
GET请求无消息体,只能携带少量数据(最多只能有1024字节)将数据放在url地址中。GET请求提交的数据放置在HTTP请求协议头中。
POST请求有消息体,可以携带大量数据,将数据放在消息体中。POST提交的数据放在实体数据中。
3. HTTP状态码
HTTP状态码:告知客户端从服务器端返回的请求结果。
1xx information 接受的请求正在处理
2xx success 请求正常完毕
3xx redirction 需要进行附加操作以完成请求
4xx client error 服务器无法处理请求
5xx sever error 服务器处理请求出错
1. 浏览器构建HTTP Request请求
应用层进行DNS解析,通过DNS将域名解析成IP地址,按照浏览器缓存、系统缓存、路由器缓存、ISP(运营商)DNS缓存、根域名服务器、顶级域名服务器、主域名服务器的顺序,逐步读取缓存,直到拿到IP地址。
应用层生成HTTP请求报文,HTTP请求报文包括起始行、首部和主体部分。
传输层建立TCP连接,进行三次握手。
网络层使用IP协议来选择路线(IP协议的路由功能)。
数据链路层实现网络相邻节点间可靠的数据连接。把数据包packet封装成帧(Frame),并按顺序传送各帧。
物理层传输数据,数据链路层的帧(Frame)转换成二进制形式的比特(Bit)流,从网卡发送出去,再把比特转换成电子、光学或微波信号在网络中传输
2. 网络传输
3. 服务器构建HTTP Response响应
服务器接收到这个比特流,把比特流转换成帧格式,上传到数据链路层,服务器发现数据帧中的目的MAC地址与本网卡的MAC地址相同,服务器拆除数据链路层的封装后,把数据包上传到网络层。服务器的网络层比较数据包中的目的IP地址,发现与本机的IP地址相同,服务器拆除网络层的封装后,把数据分段上传到传输层。传输层对数据分段进行确认、排序、重组,确保数据传输的可靠性。数据最后被传到服务器的应用层。
5. 网络传输
6. 浏览器渲染页面
参考:参考原文
TCP头部结构:
序列号seq:
占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。
确认号ack:
占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号
确认ACK:
占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效
同步SYN
连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。
终止FIN:
用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接
ACK\SYN\FIN表示标志位,值为1或0
三次握手过程——TCP建立连接
第一次握手:
客户端发送连接请求报文(SYN=1,seq=x)
第二次握手:
服务器端接收到报文后向客户端回复ACK报文(SYN=1,ACK=1,seq=y,ack=x+1),并分配资源
第三次握手:
客户端接收到ACK报文后也向服务端发送ACK报文(ACK=1,seq=x+1,ack=y+1),并分配资源。
完成三次握手。
A向B建立TCP连接,通过第一次握手B知道A能够发送数据,通过第二次握手A知道B能发送数据,第一次加第二次握手A知道B能接收数据,结合第三次握手,B知道A能够接收数据。
四次挥手过程——TCP断开连接
TCP断开连接可以是客户端发起或者服务端发起。
第一次挥手:
客户端进程发出连接释放报文(FIN=1,seq=u),停止发送数据。
第二次挥手:
服务端接收到连接释放报文,向客户端发出确认报文(ACK=1,seq=v,ack=u+1)
第三次挥手:
客户端接收到服务器的确认报文后,等待服务器端发送连接释放报文。这期间服务器将向客户端发送最后的数据。然后服务器端向客户端发送连接释放报文(FIN=1,ACK=1,seq=w,ack=u+1)
第四次挥手:
客户端接收到服务器端发送的连接释放报文后,发出确认报文(ACK=1,seq=u+1,ack=w+1)。服务器端接收到连接释放确认报文后立即关闭,但客户端会等待2∗∗MSL(最长报文段寿命)后断开。
问1:为什么要三次握手?只有两次握手可以吗?
答:三次握手可以完成两个重要功能:服务器端和客户端都知道彼此已经准备好(接收和发送);并且允许双方协商初始序列,在握手过程中发送和确认序列号。如果只有两次握手,可能发生已经失效的请求连接报文被传送到了以后产生错误。假设A向B发送一个连接请求,但请求未及时发送到B,A认为请求失败重新向B发送了一次请求,B正常收到后建立连接传输完成后释放连接。此时A第一次发送的请求到达B,B认为A再次发起请求。若是两次握手,连接就会建立成功,B会一直等待A发送数据,造成B的资源浪费。但如果是三次握手,B向A发送确认报文后A未回应则会释放连接。
问2:为什么需要四次挥手
答:第一次挥手,A向B发起请求表示A没有数据需要发送了。第二次挥手,B向A发送信号确认A的断开请求。第三次挥手B向A发送请求断开连接,表示B没有数据需要传输了。第四次挥手A向B发送确认请求,同意断开。第二、三次挥手分开是因为在第二次挥手后B可能还有最后的数据需要传输给A。挥手次数比握手多一次是因为握手通信只需要连接,而挥手过程不仅要处理连接还要处理数据。
问3:为什么客户端需要等待2MSL再关闭
答:因为网络是不可靠的,最后一个ACK可能跌势,等待时间是用来重发可能丢失的ACK报文。客户端发出最后的ACK回复后假设ACK丢失,服务器端没有收到ACK就会不断重复发送FIN片段。客户端必须等待一段时间确认服务器端是否接收到ACK,如果客户端接收到服务器端发送的FIN,就会再次发送ACK并且等待2MSL(一个发送和一个回复所需的最大时间)。
问4:什么是半连接队列?什么是全连接队列?
答:TCP三次握手后,在第一次握手后服务器端将相关信息存在半连接队列中,然后第二次握手回复确认报文给客户端。客户端发送确认报文后全连接队列没满从半连接队列拿出相关信息放入到全连接队列中。