TCP的连接、断开与状态转移

TCP提供的功能

连接:
TCP提供客户与服务器之间的连接。传输之前需要先建立连接关系。
重传:
TCP是可靠的,这与UDP不同。收端收到数据需要返回确认。如果没有收到确认,TCP会进行自动重传,并等待更长时间。数次重传失败后,TCP会放弃连接,并通知用户。
RTT:
TCP会自动估算客户和服务器之间的往返时间,将这个时间用于等待确认。由于往返时间的不稳定,TCP会持续估算一个给定连接。
排序:
TCP给每个字节关联一个序列号,并根据这个序列号对字节进行排序。假设一个应用写2048个字节到一个TCP套接字,导致TCP分成两个分节。第一个分节序列号为1~1024;第二个为1025~2048。接收端TCP可能收到错序的分节或者重复的分节,会根据这个序列号进行排序或丢弃重复分节。
流量控制:
TCP会设置通告窗口(advertised window),该窗口告诉另一个端在任何时刻它一次你个能够从对端接受多少字节的数据。在任何时刻,该窗口指出接收端缓冲区当前可用的空间量。该窗口时刻动态变化:当接受到来自发送端的数据时(存入缓冲区了),窗口就变小;当接收端从缓冲区读取数据时,窗口就变大。
全双工:
在一个给定的连接上,应用可以在任何时刻在进出两个方向上既发送数据,又接收数据。在建立全双工连接后,可以将它设置为单工连接。

TCP建立连接

(1)三次握手

TCP在建立连接时,至少需要3个分组,因此称为三次(三路)握手。
a、被动打开(passive open):
服务器准备好接受外来的连接。通常会调用socket、bind和listen这三个函数。先创建一个套接字,然后绑定端口,打开listen使这个套接字进入监听。
b、第一次握手主动打开(active open):
客户通过调用connect发起主动打开。客户TCP发送一个分节,该分节的SYN置为1,同时包括客户将在(待建立的)连接中发送的数据的初始序列号(客户的seq)。通常SYN不携带数据。
(第一个分节:SYN=1,seq=x)
c、第二次握手服务器确认:
服务器收到客户的分节,并发送一个分节,该分节将ACK置为1,告诉客户端自己确认了它的请求,同时自己也发送一个SYN=1,告诉客户端可以建立连接。该分节还包括服务器将发送的数据的初始序列号(服务器的seq),和期望收到的下一个序列号(表示已经收到客户端的序列号)。
(第二个分节:ACK=1,SYN=1,seq=y,ack=x+1)。
d、第三次握手客户确认:
客户收到服务器的ACK,并发送一个确认ACK分节,其中包括客户的下一个序列号和期望收到的服务器的下一个序列号。进入
(第三个分节ACK=1,seq=x+1,ack=y+1).

(2)三次握手过程分析

第一次:客户发送请求到服务器:服务器收到,服务器知道客户端发送正常,自己接受正常。
第二次:服务器发给客户端:客户端知道自己发送正常,接受正常,服务器接受正常,发送正常,
第三次:客户端发给服务器:服务器收到,知道双方的发送接受全部正常,可以建立连接。

三次握手的目的是,让客户端和服务端全部确认双方的发送和接收能力正常。

(3)流程图

在这里插入图片描述

TCP选项

MSS选项:使用该选项告诉对端它的最大分节大小(maximun segment size)。即在本连接中每个TCP分节最大数据量
窗口规模选项:如果不设置这个选项,TCP在进行流量控制时,可以告知对端的窗口大小最大为65535(16位)。通过设置这个选项,可以指定TCP首部的窗口必须扩大多少位(0~14)。
时间戳选项:无须考虑

TCP终止连接:

(1)四次挥手

TCP终止连接需要至少4个分节,因此被称为四次挥手。
a、第一次挥手主动关闭(active close):
发送端应用进程调用close,该端的TCP发送一个FIN分节,并附带客户端序列号。表示数据发送完毕,请求断开连接。进入FIN-WAIT-1状态
(第一个分节FIN=1,seq=u)
b、第二次挥手被动关闭(passive close):
接收端接收到断开FIN分节,回复一个收到确认ACK分节,并回复服务端序列号和期待收到的下一个客户端序列号。这个FIN也作为一个文件结束符传递给接收端的应用进程(放到正在等待被应用进程接收的数据之后),通知该应用进程在这个连接上不会再收到任何额外数据。
(第二个分节ACK=1,seq=v,ack=u+1)
c、第三次挥手服务器关闭:
一段时间后,应用进程处理完未处理的数据,调用close关闭TCP套接字,发送一个FIN给发送端,并发送ACK通知客户端,附上服务端序列号(新的序列号)和期待收到的客户端序列号。
(第三个分节FIN=1,ACK=1,seq=w,ack=u+1);
d、第四次挥手客户端确认:
客户端收到这个FIN,并回复确认ACK和序列号
(第四个分节ACK=1,seq=u+1,ack=w+1)。

(2)四次挥手过程分析

第一次:客户端请求断开
第二次:服务器确认客户端的断开请求,并处理未完成数据
第三次:服务器请求断开
第四次:客户端确认服务器的断开请求。

(3)流程图

在这里插入图片描述

总结

三次握手:				    四次挥手
SYN=1 seq=x  			    FIN=1 seq=u
						    ACK=1 seq=v ack=u+1
SYN=1 ACK=1 seq=y ack=x+1	FIN=1 ACK=1 seq=w ack=u+1		
ACK=1 seq=x+1 ack=y+1		ACK=1 seq=u+1 ack=w+1				

a、请求 SYN\断开 FIN,如果带有这两个,则一定要有回复。
b、收到任意请求都需要带有回复ACK,只发送ACK不需要对端有回复
c、每次发送自己带一个seq
d、收到别人seq回一个ack=seq+1
e、挥手比握手多一个环节,因为要等待数据处理完成。

TCP状态转移

(1)11种状态

TCP一个连接共有11种不同状态。每种状态下能够执行的操作不同,且每种状态下发送不同的分节会迁移到另一种状态。
CLOSED:初始状态。此时可以主动打开(到SYN_SENT)也可以被动打开(到LISTEN)。
LISTEN:监听状态。被动打开后到这个状态,表示服务器的某个套接字SOCKET处于监听状态。
SYN_RCVD:表示收到SYN。正常情况下,这是服务器SOCKET在建立TCP连接时的一个中间状态,比较短暂。收到客户端ACK后马上进入ESTABLISHED状态
SYN_SENT:客户端SOCKET执行CONNECT后,发送SYN报文进入该状态。该状态阻塞,并等待服务端的确认ACK。
ESTABLISHED:连接建立状态。
FIN_WAIT_1和FIN_WAIT_2:这两个状态都表示等待对方的FIN报文。区别在于:FIN_WAIT_1是套接字在ESTABLISHED状态下,它想主动关闭连接,发送FIN后会进入的状态。当收到对方ACK回复后,就进入FIN_WAIT_2状态。由于发送FIN和接收到ACK的时间较短,因此FIN_WAIT_1的持续时间较短。FIN_WAIT_2状态时间相对较长,此时表示处于半连接状态。一方(客户端)已经做好CLOSE准备,而服务端还在进行未完成的数据处理。
TIME_WAIT:客户端处于FIN_WAIT_2状态时,收到服务端FIN,并发送出ACK报文。此时会等待2MSL(最长分节生命期的两倍),如果没有再收到服务端报文,则进入CLOSED状态。
CLOSING:罕见特殊状态。客户端在发送FIN后,没有收到对方的ACK,而是同时也收到了对方的FIN。也就是双方同时发起断开连接,由FIN_WAIT_1进入该状态。
CLOSE_WAIT:等待关闭状态。服务端收到对方的FIN后,会发送一个ACK回复,此时就从ESTABLISHED进入CLOSE_WAIT状态。此时实际上在通知对端,自己已经受到了断开请求,并且已经在进行断开准备工作。这个状态下服务端会继续处理未完成数据,直到处理完成后发送断开FIN。
LAST_ACK:处于CLOSE_WAIT的服务端发送FIN后进入该状态。等待对方最后的ACK后进入CLOSED状态。

(2)状态迁移图

在这里插入图片描述
虚线:表示服务端的正常状态转换
实线:表示客户端的正常状态转换
应用:表示应用进程发起操作时发生状态转换
接收:表示接收到分节时发生状态转换
发送:表示发送分节后发生状态转换

(3)TIME_WAIT详解

客户端在FIN_WAIT_2状态下收到服务器的FIN,并发送最后的ACK确认,然后进入TIME_WAIT状态。该状态会持续2MSL(最大分节生命周期)时间,MSL通常为30s到2分钟。MSL是任何IP数据报在因特网中存活的最长时间。超过这个时间,就算没传到也会自动消失。
在这里插入图片描述
分组在网络中可能出现迷途。某分组T1从路由器A发送到路由器B时,可能A和B的链路断开了,此时路由协议可能需要较长时间才能找到新的通路。这段时间可能发生分节的循环(A到B,B再回到A)。在这个迷途期间,TCP由于收不到ACK,重传分组T2,T2通过候选路径到达了目的地。一段时间后,T1也通过新通路到达了目的地。此时T1和T2出现了重复。T1便成为了迷途的重复分组或漫游的重复分组
这个状态有两个作用:

a、使TCP连接的终止更可靠

在这里插入图片描述
客户端收到服务器的FIN ACK后,会回复一个ACK。但是最后这个ACK分节可能在传输中发生丢失
服务器没有收到最后的ACK,以为自己的FIN没有发送成功,因此会进行FIN ACK的重传。如果没有TIME_WAIT状态,客户端在收到第一个FIN ACK后就进入了CLOSED状态,此时再次收到服务端的FIN ACK,会发生错误。因此需要有TIME_WAIT状态来维持客户的状态等待2MSL后,再进入真正的CLOSED状态。至于为什么是2MSL,也很好理解:第一个ACK最多维持MSL,后来的FIN ACK也最多MSL,等到超过2MSL还没有收到新消息,说明客户端已经断开连接。

b、防止老的重复分节影响化身连接

假设某个TCP连接link1在IP地址1.1.1.1和端口13中建立,关闭link1后,在相同的ip地址和端口中建立新的连接link2。link2可以称为link1的化身。如果没有TIME_WAIT状态,那么link2有可能收到link1的某个重复老分节。因此TCP需要设置TIME_WAIT状态。TCP不会为处于下TIME_WAIT的连接发起化身。一直到连接彻底断开,即TIME_WAIT状态结束,进入CLOSED状态,才有可能出现化身。这样保证了先前连接的老的重复分节可以有充分的时间消逝

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值