TCP协议中的三次握手与四次挥手

前言:
TCP的连接与释放过程:
这里写图片描述
首先就是客户端主动发起连接、发送请求,然后服务器端响应请求,最后客户端主动关闭连接。两条竖线表示的是通讯的两端(client与server),从上到下表示的是时间的先后顺序,因为数据从一端到另外一端是需要时间的,所以是斜线。下面便分别介绍链接的建立与连接的释放。
什么是三次握手?
我们先来看三次握手建立连接的图:
这里写图片描述
第一次握手:
客户端先发送一个SYN请求(SYN=1表示该报文是一个连接请求报文),发送的序号seq=x(x是系统自己选定的大小),SYN虽然不携带数据但是会消耗一个序列号。当客户端的SYN请求发送出去之后,客户端进入SYN-SENT状态。

第二次握手:
服务器端收到客户端的连接请求报文,如果同意连接的话就像客户端发送一个确认报文。此确认报文的SYN和ACK的标志位都置为1,确认号a = x +1,同时服务器这边也要给自己设定一个发送序号y。此报文同样不能携带数据,但也要消耗一个序列号。

第三次握手:
客户端收到服务器端确认报文后,要再次向服务器端发送一个确认报文,表明我已经收到你的确认消息。此确认报文的首部ACK标志为1,确认号ACK= y+1,序号为x+1。从此报文开始,就已经开始携带数据了,若此报文不携带数据则下个报文的序号认为x+1。此后,客户端就进入了ESTABLISHED状态。

LISTEN:这个状态很容易理解,表示服务器端的某个状态处于监听状态,处于改状态的端口可以接收连接。
SYN-RCVD:这个状态表示接收到了客户端发过来的SYN报文,这个状态其实很短暂,只是个中间状态。
SYN-SENT:当客户端发送了SYN报文,会直接从CLOSED状态转换为该状态,并等待第二次发送确认报文。
ESTBLISHED:表示客户端和服务器端的链接已经建立。


为什么要进行三次握手?
采用三次握手是为了防止失效的链接请求又传到了服务器端。
eg:客户端向服务器端发送了一个请求连接报文,如果这个报文在网络中阻塞了并没有传给服务器端,所以服务器端就无法向客户端发送确认报文。客户端经过重传计时器之后就会再次向服务器端发送一个请求链接的报文,这个报文被服务器端收到并给客户端确认收到,之后客户端和服务器端开始了数据传输。在客户端和服务器的数据传输结束之后,此时服务器端收到了刚才第一次客户端发送的请求链接的报文,但是于是给客户端回复确认收到连接,但是客户端由于刚才传输已经结束它的状态就成了closed,此时没有发请求连接的报文,那么它就不会去理服务器端。那么服务器端就会一直等下去,就会造成服务器端的资源浪费的情况。
所以,两次握手是有弊端的。三次握手遇到这种情况,客户端不会因为服务器端的确认而向服务器端确认,而服务器端收不到客户端的确认就不会等待,就不会造成资源的浪费。

什么是四次挥手?
四次挥手是客户端和服务器端断开连接的过程,我们先看四次挥手的示图:
这里写图片描述

第一次挥手:
数据传输完成后要释放连接的时候,客户端的上层应用会向客户端发送连接释放的报文。并停止发送数据主动的关闭连接。客户端会向服务器发送连接释放的报文,报文的首部终止位FIN的值为1,之后客户端的进入FIN-WAIT-1的状态。

第二次挥手:
服务器端对客户端的终止终止请求报文进行应答并确认服务器端报文段的序号,发送完之后服务器端进入CLOSE-WAIT状态。此时连接处于半连接的状态,客户端已经没有向服务器端要发送的数据了,但是此时服务器端还可以向客户端发送数据。

第三次挥手:
如果服务器端没有向客户端再发送的数据,则服务器端的应用进程就会释放TCP连接。服务器端也会向客户端发送终止请求报文,发送完成之后服务器端就进入LAST-ACK状态。(最后确认状态)

第四次挥手:
客户端在收到服务器端的连接释放报文之后,再次向服务器端发送确认报文。是对第三次挥手的应答,此后客户端进入TIME-WAIT状态。客户端在发送确认报文之后不会立即结束,而是等待2MSL之后才会结束。
MSL:最大报文段寿命。
服务器端在收到客户端的确认报文之后就结束了此次连接进入closed状态。

客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。
(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。


四次挥手的状态:
FIN-WAIT-1 : 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
FIN-WAIT-2 : 从远程TCP等待连接中断请求
CLOSE-WAIT -:等待从本地用户发来的连接中断请求
CLOSING :等待远程TCP对连接中断的确认
LAST-ACK : 等待原来发向远程TCP的连接中断请求的确认
TIME-WAIT :等待足够的时间以确保远程TCP接收到连接中断请求的确认
CLOSED -:没有任何连接状态


为什么要进行四次挥手?
在TCP连接的时候ACK和SYN是一起发送的,断开连接的时候却没有一起发送。原因是:TCP是全双工的,接收到FIN意味着不会收到数据,但是却还可以发送数据。
在建立连接的时候服务器可以把SYN和ACK放在一个包中进行发送。
关闭连接的时候,一端收到FIN包此时还有数据没有发送完,就要向对方回复FIN包的ACK。将数据发送完之后再向对方发送FIN,所以分开发送。
因为是各自互相发送FIN报文,以及发送对对方FIN报文的确认报文,所以要进行四次挥手。


深入理解TCP连接的释放:
在上面我们知道TCP是全双工的,所以每个方向上的关闭都是单独的。当一方完成数据的发送任务就可以发FIN告诉对方自己发送数据结束,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
简单说来是 “先关读,后关写”,一共需要四个阶段。以客户机发起关闭连接为例:
1.服务器读通道关闭
2.客户机写通道关闭
3.客户机读通道关闭
4.服务器写通道关闭
关闭行为是在发起方数据发送完毕之后,给对方发出一个FIN(finish)数据段。直到接收到对方发送的FIN,且对方收到了接收确认ACK之后,双方的数据通信完全结束,过程中每次接收都需要返回确认数据段ACK。

主动断开链接的一方为什么要进入TIME_WAIT?
TIME-WAIT状态是为了等待足够的时间来确保远程TCP接收到连接中断请求的确认。
因为主动断开连接的一方先发送FIN报文,对方会给你回复它知道你发完了,等它给你发完数据之后,它也会给你发FIN报文,此时你给它回复确认收到它的FIN报文后进入TIME-WAIT状态。因为此时要等你发的确认报文等它收到才会closed,但是万一网络上很拥堵所以要进入TIME-WAIT状态。
TIME_WAIT是TCP协议用以保证被重新分配的socket不会受到之前残留的延迟重发报文影响的机制,是必要的逻辑保证。
后序:
关于TCP方面后序还会仔细将TIME-WAIT状态做一个说明,还会将定时器,滑动窗口、拥塞控制、超时重传进行说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值