TCP协议总论

TCP总论

在网络传输中,从一个A主机发送数据到B主机可能会遇到如下问题:

1.由于网络传输过程中的bit位错误,解析错误,路由表更新,线路故障等情况.B可能收不到数据包.或者收到有损的数据包.
2.A要发送的数据太多,一个以太帧的数据部分无法存储全部信息,只能进行ip分片,发送多个数据包到B,而网络延迟可能导致B收到数据包的顺序是错乱的.
4.A可能要发多个应用程序的不同数据包给B,B需要给这些数据包进行归类
3.当网络链路中的某些节点处理数据太多导致速度特别慢,需要控制流量

TCP的出现就是为了解决以上问题.

TCP的特点

TCP的特点就是

  • 提供字节流服务
  • 可靠
  • 面向连接

所谓面向连接指的是,A主机要和B主机交换信息必须先建立一个A到B的TCP连接.类似于打电话,先建立连接,接通电话说Hello后就可以交流了.

所谓提供字节流服务是指,当建立连接之后,发送方只用把一段段的字节流给TCP,TCP根据情况发送,而不用考虑将其封装成一个个数据包,而接受方也是接受一段段的字节流,然后回复我收到了哪些数据包.如果发送方在一段时间内没有收到回复会重发.接受的数据包是带有序号的,接收方可以根据序号进行排序和去重.

UDP面向报文
UDP对于应用提供的数据只是简单的加上UDP头部,再重重封装成一个以太帧.

TCP面向字节流
TCP对于应用提供的数据将其视为一段段的字节流,会将其先存储到缓冲池中,根据网络的拥塞情况确定发不发送发送多少.

TCP数据包

TCP数据包由标头和数据构成
TCP的数据包放在IP数据包的数据部分,IP数据包头部的protocol会指定数据包的协议为TCP
一个完整的TCP数据包如下:
TCP数据包

其中数据序号来自对字节流中每个字节的编号,用来指定接收到的数据在完整数据流中的位置,数据序号是这段数据的第一个字节的编号.

确认序号是用来表示下一次希望收到数据包中的数据序号

UAPRSF这五个位置都是标记位,用来表明TCP连接的目的,分别是
URG:紧急位,和紧急指针一起使用
ACK:确认位,基本所有情况下ACK都为1,表示确认,主动发起也是1(响应上一次)
PSH:推送位,为1表示这个tcp请求请尽快响应
RST:重置位,用来关闭异常连接.
SYN:同步位,为1表示这是一个新连接
FIN:结束为:为1表示希望断开连接

RST的作用,例如AB连接通讯过程中,A给B发送断开连接的请求,而B由于一些原因(线程重启)自身断开了连接,此时B收到A的请求时不想处理就直接发送RST要求断开.

窗口字段是接收方用来控制发送方发送的最大字节长度的

包校验和是用来校验TCP数据包的完整性和正确性,虽然以太网也有数据校验的功能,但TCP仍然提供了校验方式.

紧急指针是用来告诉另一端有“紧急数据”,指针的值时被放置在普通的数据流中的紧急数据的位置,而对“紧急数据”的处理留给对方决定。

TCP连接

cp连接每收到一个报文都需要回应确认.
以client向server请求一张图片(应用层使用http)为例

数据序列(seq)与确认序列(ack)

需要注意的是这里的ack并不是ACK标志位,ack的值通常是上一次收到的seq加上数据长度,如果收到的单纯是回复确认(数据部分空)不会再此基础上加1,如果是有目的性的请求且数据部分为空则加1,如果数据部分有数据则是数据长度加上上次收到的seq值.

可以理解seq实际上是tcp发送的数据部分第一个字节的对应序列号

seq值在第一次发送到对端时,会通过散列函数生成一个随机数,之后会增加.可以理解为在初始化起始值后给tcp缓冲池中的每个字节按顺序递增加1编码,传输时将数据的第一个字节的编码作为seq,发送确认报文时会直接在上一次的基础上加1

由于三次握手过程中需要client和server分别给对端进行第一次连接,所以有client和server都有自己的初始seq

对于从一端连续发起的多次请求,它们的ack值和seq值都是一样的

对于ACK的数据包是不消耗序号的,而PSH,SYN,FIN都是要消耗序号的

三次握手建立连接

首先Client会发送一个数据包来启动连接:

这里Client会初始化一个随机的seq放到数据序号位,然后会在SYN位标记1,代表这是一个新连接.

在这里插入图片描述

server收到启动连接的请求后回复一个确认收到的数据包:

server也会初始化一个随机的seq用于数据序列,然后会在之前收到的seq的基础上加1作为ack,指的是希望下次收到来自Client的数据包的seq,通常会用相对client发过来的初始seq而言的大小1来表示

server到client也是第一次连接,所以会有SYN位,同时ACK位也为1

在这里插入图片描述

client收到server的确认回复之后也会发一个确认回复给server:

由于这是一个确认包所以ACK位为1,同时client在上次发送的seq的基础上加1作为seq,同样client也会设置ack值为希望下一次收到server端的seq

在这里插入图片描述

client和server建立连接的每次通信叫做握手,这就是三次握手.三次握手完成之后就建立了连接

建立连接之后就可以做应用数据的传输了

client向server请求图片

建立连接之后,client使用http协议向server请求一张图片.

client发送http请求

client端将数据使用http协议封装后放到tcp的数据部分,同时设置PSH位为1,意思是希望server尽快响应.并设置ACK位为1

发送的seq则是上次server发回的确认报文中的ack值,而ack值是上次server发回的确认报文中的seq+1

在这里插入图片描述

server收到http请求,回复确认

server收到http请求之后,回复确认数据包,在上一次发送的seq的基础上加1作为seq,而ack值则是收到的seq值+http数据包长度

在这里插入图片描述

server使用http发送图片给client

server将图片数据封装成http数据包放到tcp数据部分,设置PSH和ACK都为1,要求尽快处理.同时设置seq为client要求的数值,设置ack值为上次收到的seq+http数据包长度
在这里插入图片描述

client收到图片信息,回复确认

client收到数据包后,解析http协议取出图片信息,回复确认,设置ack为1,取出当前数据的第一个字节的seq,同时设置ack值为收到的seq值+tcp数据部分长度

在这里插入图片描述

server探测client是否还在,保活

server发送保活(Keep-alive)报文
这里的Keep-alive报文不一定会发送,http头部可以设置,keep-alive报文是为了确认对端是否还在连接状态.

保活报文的seq值会是对端上次发回的ack值-1,数据内容为空,而ack的值则是上次收到的seq+1
在这里插入图片描述

client收到保活报文,回复确认
client端收到保活报文的话回复确认,seq值为收到的ack值,而ack值则是收到的seq+1
在这里插入图片描述

tcp四次挥手断开连接

server提出关闭请求
server提出断开连接申请,将FIN位值为1,ACK位为1,并取出字节流的第一个字节的seq作为seq值,同时设置ack值为上次收到的具有有用信息或目的的数据包seq值+1或seq值加数据长度
在这里插入图片描述

client收到关闭请求,回复确认
client收到关闭请求,回复确认,设置ACK位为,设置ack为收到的seq值加1,在上次发送的seq基础上加1作为seq
在这里插入图片描述

client也提出关闭请求
client提出关闭请求,将FIN位值为1,ACK位为1,在上次发送的seq基础上加1作为seq,设置ack值为上次FIN请求的seq+1

在这里插入图片描述

server收到关闭请求,回复确认
server收到关闭请求,回复确认,设置ACK位为1,设置ack值为上个FIN请求的seq+1,设置seq值为上次发送的seq值加1
在这里插入图片描述

总流程

总的概略流程:
在这里插入图片描述

在这里插入图片描述

TCP可靠

TCP可靠的主要实现方法

  • 序号确认机制
  • 重传机制
  • 定时器
序号确认机制

由于seq和ack的存在,tcp可以对接收的tcp数据包进行重组排序和去重.

对于很多段连续的数据包,可能会丢失数据包,对此TCP的确认机制有两种:

1.对于丢失的数据包,采取遗弃的处理

对于顺序如下的报文(数字表示序列号seq):

1 - 100101 - 200201 - 300301 - 400

其中接收方未收到101-200的数据包,接收方会直接将101-400的数据全部丢弃.不回复确认,待服务器重传.这样做实现简单,而且不需要缓存201-400的数据包.但是对于网络的消耗较大.

2.对于丢失的数据包,将其他数据包缓存起来,待丢弃的数据包收到后一起给应用.

1 - 100101 - 200201 - 300301 - 400

其中接收方未收到101-200的数据包,接收方会将其他收到的数据先缓存起来,回应确认时将ACK设置为101主动要求重传101-200的数据,收到重传之后回复确认时,设置ACK为401.

超时重传机制

发送方在发送数据之后会开启重传定时器,在一定时间之内(RTO(Retransmission TimeOut))没有收到ACK的话,将会从缓冲中取出再进行发送.

RTO设置过大将降低数据的吞吐量,RTO设置过小又会消耗不必要的网络资源.通常RTO由如下公式计算得出最佳值

RTO=RTT+4RTTD

注释:
RTT:Round Trip Time 往返时延
RTTD:Round Trip Time deviation 往返时延偏差

实际上由于网络环境的差别,tcp会记录每个数据包发送到接收的时间差(往返时延)取平均值之后算得最佳的RTO.

定时器

TCP中主要有四类定时器用于保证TCP的可靠

  • 重传定时器
  • 持续定时器
  • 保活定时器
  • 时间等待计时器

1.重传定时器,主要是用于超时重传.
2.持续定时器,主要用于当窗口更新报文丢失时,定时发送方给接收方发送窗口更新探寻报文,避免死锁的情况.
3.保活定时器,主要用于服务器发送保活报文时,未收到ACK,将定时发送保活报文,超过10次未ACK,TCP连接就将自动断开.
4.时间等待计时器,主要用于在关闭TCP连接时,设置一定时间过渡,以避免有报文未接受到,一般为报文段期望生命周期的两倍

TCP流量控制

TCP通过可变大小的滑动窗口的方式来实现流量控制,接收方缓冲池的有限导致能接收的数据有限,接收方会设置窗口字段(取拥塞窗口(cwnd)和接受窗口(rwnd)的较小值)来调控发送方能发送的最大数据字节长度.

当接收方没有空间接收时回应确认将窗口字段设置为0.发送方收到确认时就会开启持续定时器.

TCP拥塞控制

TCP拥塞控制主要是避免网络的拥塞和缓解已存在的拥塞,TCP用拥塞窗口来衡量网络的拥塞程度。在接受窗口和拥塞窗口中取小来设置窗口字段。

拥塞:当发送方在一定时间内没有收到回复,认为是拥塞.
ssthresh:门限值,避免因发送数据过大导致拥塞,是拥塞控制算法切换的阈值.他的值为出现拥塞时发送窗口值的一半
MSS:最小分段大小

TCP拥塞控制的主要算法有如下:

1.慢启动,当TCP建立连接时或者已经发生拥塞时,在cwnd<门限值(ssthresh)时,将cwnd的值设置成一个报文段大小。每经过一轮次就将cwnd加倍(指数增加)
2.拥塞避免,当cwnd>=ssthresh时,为避免拥塞,每轮次cwnd只增加一个报文段长度(线性增加)
3.快速重传,在发送方连续收到三个重复的ACK时,直接重传,不再等待重传定时器到时。
4.快速恢复,采用快速重传时直接执行拥塞避免算法提高网络效率。

这四种算法的装换过程如下
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值