传输层-4、TCP协议
参考哈工大公开课。
TCP概述:
TCP是一种点对点的协议,就是只有一个发送方,一个接收方,且同一连接中能够传输双向数据流。它的数据传输是可靠的、按序的字节流,采用了流水机制通过设置窗口并且实现了TCP拥塞控制和流量控制,由于采用了流水机制,所以接收方和发送方都有缓存空间。
TCP是面向连接的协议,它有三个特点:
1、 通信双方在发送数据之前必须建立连接。
2、 连接状态只在连接的两端中维护,在沿途的节点中并不维护状态。
3、 TCP连接包括:两台主机上的缓存,连接状态变量,socket等。
TCP段结构和传输过程:
图一:TCP段结构
Sequencenumber(***):
***指的是Segment中第一个字节的编号,而不是segment的编号;建立TCP连接时,双方随机选择***。
Acknowledgemetnumber(ACK***):
希望接收到下一个字节的***,并采用累计确认方式,就是在该ACK***之前所有字节均已被正确接收到。如果接收方接收到了乱序的Segment,TCP协议中没有规定,由TCP的实现者做出的决策。
图二:TCP传输过程
1、 Host A 发送TCP段给Host B,Seq=42、ACK=79、data=’C’;这个Segment中第一个字节的编号是42,希望接收到的数据报是79,数据为C。
2、 Host B 回复TCP段给Host A,Seq=79、ACK=43、data=’C’;这个Segment中第一个字节的编号是79,希望接收到的数据报是43,数据为C。
TCP可靠数据传输概述
TCP在IP层提供的不可靠服务基础上实现可靠数据传输服务,采用了流水机制和累计确认,并使用单一重传定时器。触发重传的事件有两种:1、超时;2、收到重复的ACK。
TCP发送方事件:
首先,运输层从应用层收到数据,收到数据后创建Segment,设置Segment的第一个字节的编号为***,并开启计时器,设置超时时间。当超时没有收到正确的ACK,发送方会重传引起超时的Segment并重启定时器。当收到ACK之后,如果确认此ACK是此前没有确认的Segment,就更新Segment之前的数据为已经发送成功,并更新SendBase(窗口)。如果SendBase中还有没有确认的分组,就重启定时器。
TCP三种异常事件:
A、 接收方发给发送方的ACK丢失了,由于发送方没有接受到ACK,那么等待超时之后就会重新发送。
B、 Timeout设置短了,在接收到ACK之前等待就超时了,发送方在接收到ACK之前已经开始重新发送了,导致了资源的浪费。
C、 C情况是发送方发送了两个数据报,接收方正确接收到了数据报并发送了返回发ACK,但是ACK(100)小的就丢失了,而ACK(120)大的被发送方正确接收了,由于TCP采用的累计传输,即使ACK=100没有被接收,发送方依然会认为接收方已经接收到了***为100的Segment已经正确接受了。所以就会移动窗口,更新SendBase=120。
图三:三种典型的重传事件
快速重传机制:
核心思想:根据接收打到ACK重复的次数,在定时器超时之前就开始重传。
TCP的实现中,如果发生超时,超时时间间隔会重新设置,并且超时时间间隔会加倍,导致其超时间隔会越来越大,这样就会让重发丢失的分组之前要等待很长时间。
重复ACK检测分组丢失:因为重复接收到了相同的ACK,所以发送方会认为接收方接收到重复的数据,那么发送方就会接着发送ACK后面的Segment。
TCP流量控制:
TCP流量控制的核心思想,在图一TCP段中的ReceiveWindow中记录了接收方剩余缓存大小,如果缓存太小,发送方就放慢发送的速度;如果缓存为0,发送方还是会发送数据报,只是速度会更慢,这里发送方不能停止发送,因为接收方的随着时间的进行,缓存里面的数据会交给应用层,缓存会空下来,如果发送方停止发送Segment,那么发送方就不可能知道接收方的缓存已经有空余了,这样就不能重新发送剩下的数据报了。
TCP连接管理:
TCP在建立连接之前会初始化TCP变量,包括Sequencenumber(***)、缓冲区、流量控制信息等。
TCP连接需要三次握手:
第一步:client发送不携带数据TCP报文段给Service,将SYN置为1,表示要建立连接;同时还要发送初始***(Sequence number)。
第二步:service接收到SYN之后,如果同意连接,就会在自己那里设置一个缓冲区;同时向client发送一个SYNACK,其中包含service的一个初始***(Sequence number)。
第三步:client接收到了SYNACK,就会回复一个确认的Segment,告诉service确认连接。
图四:TCP连接需要三次握手
TCP关闭过程:
TCP关闭连接可以分四个步骤:
第一步:client向service发送TCP 结束(FIN)控制Segment,告诉service要关闭TCP连接;
第二步:service收到FIN,回复ACK,告诉client已经接收到了关闭连接请求;然后关闭连接,并发送FIN,告诉client已经完成TCP关闭。
第三步:client收到FIN后,回复ACK就进入等待,如果又收到FIN,就重新发送ACK。
第四步:service收到ACK,就关闭连接。
图五:TCP关闭过程