首先举一个生活化的例子,当你和朋友打电话时,你可能会使用三次握手和四次挥手的过程进行类比:
三次握手(Three-Way Handshake):
-
你打电话给朋友:你首先拨打你朋友的电话号码并等待他接听。这就像客户端向服务器发送一个连接请求。
-
朋友接听电话:如果你朋友接听了电话,他会告诉你:"喂,我在这里!"这表示你的连接请求已经被接受。这就像服务器发送一个确认消息给客户端。
-
你确认朋友的回答:在你确认朋友在电话线的另一端时,你会说:"好的,我听到了!"这表示你已经知道连接已经建立了。这就是客户端再次向服务器发送一个确认消息。
四次挥手(Four-Way Handshake):
-
通话结束:当你和朋友的谈话结束时,你会说:"好的,我得挂了。"这就像客户端发送一个关闭连接的请求给服务器。
-
朋友确认挂断:你的朋友会回答:"好的,再见!"这表示服务器已经收到了关闭连接的请求,并且也准备好关闭连接。但是他仍然会等待任何未处理的数据。这是服务器发送一个确认关闭的消息给客户端。
-
朋友准备好了:一旦你的朋友处理了所有数据,他会再次说:"好的,现在我也准备好了,我们断开连接吧!"这就像服务器发送一个关闭连接的请求给客户端。
-
确认断开连接:你会回答:"好的,再见!"这表示客户端收到了服务器的关闭请求,并且也准备好关闭连接。这就是客户端发送一个确认关闭的消息给服务器。
1.详细讲一下TCP的三次握手与四次挥手
三次握手(Three-Way Handshake)
-
第一步:客户端发送 SYN 请求
- 客户端向服务器发送一个SYN(同步)标志位的数据包,表明客户端想要建立连接。该数据包中还包含客户端的初始序列号(Sequence Number)。
-
第二步:服务器确认 SYN 请求
- 服务器收到客户端发送的SYN请求后,会发送一个SYN-ACK(同步-确认)标志位的数据包作为响应。这个数据包中的SYN标志位表示服务器接收到了客户端的SYN请求,ACK标志位表示服务器同意建立连接,并在确认号(Acknowledgment Number)字段中回复客户端的初始序列号+1,同时也会发送自己的初始序列号。
-
第三步:客户端确认 SYN-ACK
- 客户端收到服务器的SYN-ACK响应后,会发送一个确认数据包,其中ACK标志位置为1,表示客户端确认收到了服务器的响应。同时,客户端会将确认号设置为服务器初始序列号+1。
完成这个过程后,TCP连接就建立起来了,双方可以开始进行数据传输。
四次挥手(Four-Way Handshake)
-
第一步:客户端发送关闭连接请求
- 当客户端决定关闭连接时,会发送一个FIN(结束)标志位的数据包给服务器,表示客户端不再有数据要发送了,但仍可以接收数据。
-
第二步:服务器确认关闭请求
- 服务器收到客户端的FIN后,会发送一个ACK确认数据包,表明服务器收到了关闭请求。服务器在这个响应中可能还会包含一些剩余数据,如果有的话。
-
第三步:服务器发送关闭请求
- 当服务器也准备好关闭连接时,会发送一个FIN标志位的数据包给客户端,表明服务器不再有数据要发送了。
-
第四步:客户端确认关闭请求
- 客户端收到服务器的FIN后,会发送一个ACK确认数据包给服务器,表明客户端收到了关闭请求。然后等待一段时间,确保服务器收到了这个确认,最后关闭连接。
完成这个过程后,TCP连接就彻底关闭了,双方不再进行数据传输。
2.为什么是三次握手不是两次呢,为什么是四次挥手不是三次呢?
为什么是三次握手而不是两次?
- 第一次握手(SYN):客户端向服务器发送连接请求,并指明初始序列号。
- 第二次握手(SYN + ACK):服务器收到请求后,确认连接请求,并发送自己的序列号。
- 第三次握手(ACK):客户端收到服务器的确认后,也发送确认消息,表示连接已建立。
三次握手的设计是为了解决可能出现的两种情况:重复连接请求和延迟的连接请求。通过三次握手,确保了双方的状态都同步了,建立了可靠的连接。
为什么是四次挥手而不是三次?
- 第一次挥手(FIN):客户端发送关闭连接请求。
- 第二次挥手(ACK):服务器收到关闭请求后,发送确认消息。
- 第三次挥手(FIN):服务器在关闭连接之前,先发送关闭连接请求。
- 第四次挥手(ACK):客户端收到服务器的关闭请求后,发送确认消息,完成连接的关闭。
四次挥手的设计是为了确保双方都能够知道连接已经关闭,避免出现半关闭状态,即其中一方已经关闭了连接,而另一方还在发送数据的情况。
3.get和post的区别,分别适用于什么场景?
总结
get()请求是一种 HTTP 方法,用于从服务器检索数据。它将请求的数据附加在 URL 后面,以查询字符串的形式出现。特点:
- 安全性和隐私性较低,因为请求数据暴露在 URL 中。
- 数据量有限制,通常不超过 2KB。
- 适合请求无状态的操作,如页面跳转、检索数据等。
post()请求是一种 HTTP 方法,用于向服务器发送数据。它将数据存储在请求体中,不会出现在 URL 中。特点:
- 安全性和隐私性较高,因为数据不暴露在 URL 中。
- 数据量较大,没有大小限制。
- 适合请求有状态的操作,如表单提交、上传文件等。
适用场景
(1)GET 请求适用于:
数据检索:如查询数据库记录。
页面跳转:如导航到其他页面。
无状态操作:如天气预报、新闻检索等。
(2)POST 请求适用于:
数据提交:如表单提交、上传文件。
数据创建:如添加新记录到数据库。
有状态操作:如购物车结算、用户登录等。
无状态操作和有状态操作的区别:
- 无状态操作:指的是每次请求都是独立的,不依赖于之前的状态。服务器处理请求时,不会考虑之前的请求或会话信息。这使得无状态操作易于扩展和维护,因为服务器不需要存储任何会话信息。GET请求通常用于无状态操作。
- 有状态操作:指的是请求可能会改变服务器的状态,或者依赖于之前的请求或会话信息。有状态操作通常需要服务器存储一些信息,比如用户的会话状态或事务状态。POST请求通常用于有状态操作。
深入理解
1.GET 和 POST都是http请求方式, 底层都是 TCP/IP协议;通常GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包(但firefox是发送一个数据包),
2.对于 GET 方式的请求,浏览器会把 http header 和 data 一并发送出去,服务器响应 200
(返回数据)表示成功;
而对于 POST,浏览器先发送 header,服务器响应 100, 浏览器再继续发送 data,服
务器响应 200 (返回数据)。
参考链接: