TCP的连接建立过程
各种标志含义
SYN - 创建一个连接/同步标志
FIN - 终结一个连接
ACK - 确认接收到的数据
ack - 确认号
seq - 报文段序号
连接建立过程
1.服务器初始化
B的TCP服务器进程先创建传输控制块,准备接受客户端的连接请求。然后服务器进程就处于LISTEN(监听)状态,等待客户的连接请求。
2.客户端初始化,并发送连接请求
A的TCP客户端进程也是首先创建传输控制块,然后向B发出连接请求,这时首部中 SYN = 1,同时选择一个初始序号 seq=x。TCP规定,SYN报文段不能携带数据,但需要消耗掉一个序号(seq=x)。这时,TCP客户端进入SYN-SENT(同步已发送)状态
3.服务器接收请求,并向A发送确认
B收到连接请求后,如果同意建立连接,则向A发送确认。在确认报文段中 SYN=1 ACK=1,确认号ack=x+1, 同时也为自己选择一个初始序号 seq=y。注意这个报文段也不能携带数据,但同样要消耗到一个序号。这是TCP服务器进程进入 SYN-RCVD(同步收到/连接请求收到)状态
4.TCP客户端进程收到B的确认后,还要向B给出确认
确认报文段的ACK=1, 确认号 ack=y+1, 而自己的序号 seq= x+1。这时TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。
当B收到A的确认后,也进入ESTABLISHED(已建立连接)状态
连接的建立为什么要经过第三次握手
防止已经失效的连接请求报文突然又传送到了B,因而产生错误
A发出的第一个连接请求报文段并没有丢失,而是在某些网络结点长时间滞留了。但B收到此失效的连接请求报文段后,就会误认为是A又发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出请求,新的连接就建立。由于现在A并没有发出建立连接的请求,因此不会理会B的确认,也不会向B发送数据。但是B会以为新的连接已经建立,而等待A发送数据,这样B会消耗很多资源。如果采用了三次握手的话就会防止上述现象。
TCP的连接释放过程
连接释放过程
1.客户端A发送连接释放报文段,并停止再发送数据,主动关闭TCP连接(第一次挥手)
A把连接释放报文段首部的FIN置为1,其序号seq=u,它等于前面已传送过的数据的最后一个字节的序号加1。这时A进入FIN-WAIT-1(终止等待1)状态,等待B的确认。
2,服务器B收到连接释放报文段后立即发出确认(第二次挥手)
确认号是ack=u+1, 而这个报文段自己的序号是v,等于B前面已传送过的数据的最后一个字节的序号加1.然后B就进入CLOSE-WAIT(关闭等待)状态。
TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时的TCP连接处于半关闭状态,即A已经没有数据要发送了,但B若发送数据,A仍然要接受。也就是从B到A这个方向的连接并没有关闭。这个状态还会维持一段时间。
3.A收到B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段
4.若B已经没有要向A发送的数据,这时B就会发出连接释放报文段(第三次挥手)
该报文段FIN=1,序号seq=v+n(因为在这期间,B可能又发送了一些数据)。B还必须重复上次已发送的确认号 ack=u+1,这时B就进入LAST-ACK(最后确认)状态,等待A的确认
5.A在收到B的连接释放报文段后,立即发出确认 (第四次挥手)
在确认报文段中把ACK置1,确认号ack=v+n+1,而自己的序号是seq=u+1。然后进入到TIME-WAIT(时间等待)状态。
6.经过“一段时间(最长报文段寿命*2)”,TCP连接才完全释放
为什么A在TIME-WAIT状态必须等待一段时间才会完全关闭TCP连接呢?
为了保证A发送的最后一个确认报文段能够到达B。如果这个报文段没有到达B,则B会超时重传连接释放报文段。如果不等待一段时间直接进入CLOSED状态,则A不会再发送一次确认报文段,进而导致B无法按照正常步骤进入CLOSE状态。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。