1、三次握手

第一次握手:客户端向服务器发送一个SYN连接请求报文段,报文段的首部中 SYN标志位置为 1,序号字段是一个任选的随机数。它代表的是客户端数据的初始序号。

第二次握手:服务器端接收到客户端发送的 SYN 连接请求报文段后,服务器首先会为该连接分配 TCP缓存和变量,然后向客户端发送SYN ACK报文段,报文段的首部中 SYN和ACK标志位都被置为1,代表这是一个对SYN连接请求的确认,同时序号字段是服务器端产生的一个任选的随机数,它代表的是服务器端数据的初始序号。确认号字段为客户端发送的序号加一。

第三次握手:客户端接收到服务器的肯定应答后,它也会为这次TCP连接分配缓存和变量,同时向服务器端发送一个对服务器端的报文段的确认。第三次握手可以在报文段中携带数据。

总的来说,TCP三次握手的建立连接的过程就是相互确认初始序号的过程,告诉对方,什么样序号的报文段能够被正确接收。第三次握手的作用是客户端对服务器端的初始序号的确认。如果只使用两次握手,那么服务器就没有办法知道自己的序号是否已被确认。同时这样也是为了防止失效的请求报文段被服务器接收,而出现错误的情况。

2、四次挥手

第一次挥手:客户端认为没有数据要再发送给服务器端,它就向服务器发送一个FIN报文段,申请断开客户端到服务器端的连接。发送后客户端进入 FIN_WAIT_1状态。

第二次挥手:服务器端接收到客户端释放连接的请求后,向客户端发送一个确认报文段,表示已经接收到了客户端释放连接的请求,以后不再接收客户端发送过来的数据。但是因为连接是全双工的,所以此时,服务器端还可以向客户端发送数据。服务器端进入CLOSE_WAIT状态。客户端收到确认后,进入FIN_WAIT_2状态。

第三次挥手:服务器端发送完所有数据后,向客户端发送 FIN 报文段,申请断开服务器端到客户端的连接。发送后进入 LAST_ACK 状态。

第四次挥手:客户端接收到 FIN 请求后,向服务器端发送一个确认应答,并进入 TIME_WAIT 阶段。该阶段会持续一段时间,这个时间为报文段在网络中的最大生存时间,如果该时间内服务端没有重发请求的话,客户端进入CLOSED 的状态。如果收到服务器的重发请求就重新发送确认报文段。服务器端收到客户端的确认报文段后就进入 CLOSED 状态,这样全双工的连接就被释放了。

TCP使用四次挥手的原因是因为TCP的连接是全双工的,所以需要双方分别释放到对方的连接,单独一方的连接释放,只代表不能再向对方发送数据,连接处于的是半释放的状态。
最后一次挥手中,客户端会等待一段时间再关闭的原因,是为了防止发送给服务器的确认报文段丢失或者出错,从而导致服务器端不能正常关闭。

3、为什么连接的时候是三次握手,关闭的时候却是四次握手?

因为当服务器端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务器端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,"你发的FIN报文我收到了"。只有等到我服务器端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

4、为什么不能用两次握手进行连接?

3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

5、如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

posted on 2021-05-16 14:00  李起桉  阅读(90)  评论(0编辑  收藏  举报