一个不为人知Http协议

Http

所谓的超文本传输协议,也是最常用的应用层协议,一直被广泛的应用于Web和手机端,其底层依赖于TCP/IP协议。4

字节二面考的知识,让我非常蒙蔽,对Http的了解可谓是少之又少,

字节二面

Http是如何传输数据的

Http是如何传输的,那我就去了解一下:

  1. 首先客户端会初始化一个socket(下面会讲解什么是socket)。
  2. 其次服务端内面已经有一个socket对这个端口进行监听(socket初始化时已经绑定好了这个端口),时刻等待着客户端的连接。
  3. 客户端的socket和服务端的socket正式建立连接,这时候就有了三次握手(下面会详细讲解三次握手和四次挥手)。
  4. 服务端与客户端建立连接后就可以传输数据了,如果是Http连接的话,只能是请求响应的方式,客户端向服务端发送请求,服务端才能响应处理请求,而socket连接的话,服务端可以直接向客户端传输数据。
  5. 当断开连接时,TCP协议会进行四次挥手,然后与服务端断开连接。

下面就开始解决上面传输过程中的理论坑了

1.Socket

socket是什么,他是一个接口或者称之为API,只有通过socket我们才能使用TCP/IP,也就是说socket是对TCP/IP的封装,它可以为Http提供网络通信的能力。

socket的中文为套接字,之前提到过socket连接需要客户端和服务端的socket进行连接,也就是需要一对套接字,一个运行在客服端,一个运行在服务端。对上文进行解释一下,socket连接需要三个步骤,也就是服务端对端口的监听,客户端对服务端的请求,双方的连接确认。而这个双方确认就是三次握手的过程。

socket可以使用TCP协议,也可以使用UDP协议,所谓的socket连接其实就是TCP连接,三次握手和四次挥手也就是这么来的。

注意:
Http连接最显著的特点就是前面所提到的,请求响应式连接,每次的客户端请求都需要服务端的响应,一次连接只能响应一次请求,然后会主动断开连接。如果想要获取实时信息,需要客户端定时向服务器发送请求来获取新的数据。
而使用socket连接会建立长连接状态,服务端可以随时向客服端发送请求,但是socket连接要定时告诉网络中所经过的结点(路由器,网关,还有防火墙等)该连接处于活跃状态。

2.TCP的三次握手

三次握手和四次挥手是应届毕业生必考的面试问题,别问我为什么知道,因为我就是!!!

  1. 握手的时候客户端是关闭的状态,而服务端正处于监听的状态,前文已经说过了,这里只是提醒一下。
  2. 双方的第一次握手:客户端会给服务端发送一个SYN报文,也就是连接报文,SYN=1,并且初始化序列号为X,而且此报文无法携带数据。而此时客户端处于SYN_SENT状态。
  3. 双方的第二次握手:服务端就收到了SYN连接报文后,依旧是给对方发送一个SYN连接报文,而此时的SYN=1,ACK=1(确认收到了你的报文),确认号ack=x+1,此报文依旧不能携带数据,初始化序列号设置为y,而此时服务端正处于SYN_RCVD状态。
  4. 双方的第三次握手:客户端接收到服务端的SYN报文后,会给服务端发送一个ACK确认报文,ACK=1,确认号ack=y+1(表明收到服务端的报文),序列号设置为x+1(因为是第二个报文),ACK报文可以携带数据,不携带数据就不会消耗序列号。此时双方都处于ESTABLISHED状态。

注意

  1. 第一次握手为的是让服务端知道客户端拥有发送能力。
  2. 第二次握手为的是让客户端知道服务端拥有发送能力和接受能力。
  3. 第三次握手为的是让服务端知道客户端拥有接受能力。
  4. socket编程中,客户端执行connect()会触发三次握手。
  5. 如果服务端发送的SYN-ACK包客户端没有接收到,服务端会进行第一次重传,如果认为收到确认包,进行第二次,如果重传次数大于规定的最大重传次数,系统会将该连接从连接队列中移除。(每次重传的间隔时间不同,一般会指数增长)

3.TCP的四次挥手

  1. 第一次挥手:客户端向服务端发送一个FIN报文(关闭连接),此时客户端处于FIN_WAIT1状态,停止再发送数据,等待服务端确认。
  2. 第二次挥手:服务端收到FIN报文,并且向客户端发送ACK报文(确认收到),此时服务端处于CLOSE_WAIT状态,TCP连接处于半关闭状态,客户端收到服务端的ACK报文后,处于了FIN_WAIT2状态,等待服务端发送连接释放报文(FIN报文)。
  3. 第三次挥手:服务端向客户端发送一个FIN报文,此时服务端处于LAST_ACK状态(最后确认状态),等待服务端进行确认。
  4. 第四次挥手:客户端收到FIN报文,并且向服务端发送一个ACK报文(确认收到),此时客户端处于TIME_WAIT状态,过一段时间(计时器设置的2MSL时间)后确保ACK报文到达服务端后,进入CLOSED状态。

注意
MSL为一个TCP报文最大存活时间,2MSL等待时间是如果最后的ACK报文没有到达服务端,服务端会重新发送一个FIN报文,这样可以确保客户端会再次接收到。目的是为了保证客户端和服务端都可以正常关闭。如果客户端发送完最后的ACK报文后关闭,一旦丢失,服务端就无法进入正常的关闭状态了。

总结一下:

  1. 保证客户端发送的最后一个ACK报文段能够到达服务端。
  2. 防止“已失效的连接请求报文段”出现在本连接中。
发布了56 篇原创文章 · 获赞 3 · 访问量 1184

猜你喜欢

转载自blog.csdn.net/qq_40788718/article/details/103302845