TCP学习笔记

目录

TCP头部

TCP连接建立和拆除

TCP 3-WAY握手

TCP 4-WAY 挥手

TCP可靠传输

缓存区与窗口

发送缓存SBUFF和发送窗口SWND

接收缓存RBUFF和接收窗口RWND

TCP确认机制

拥塞窗口(CWND)

TCP拥塞控制

慢启动

拥塞避免

快重传

快恢复

全局同步


部分图例摘取自《计算机网络(第7版)》- 谢希仁

TCP是一种面向连接的传输层协议。在无连接的IP业务中实现面向连接,需要实现:

  1. 传输前要知会对端传输即将开始;
  2. 传输过程中信息必须按顺序完整送达;
  3. 传输结束要知会对端传输完毕。

对于1、3而言,TCP使用3-WAY握手、4-WAY挥手机制建立和拆除连接。对于2,TCP采用序列号和确认来确保信息的按顺序完整送达。而且使用了拥塞避免的方法,尽可能匹配发送方和接收方的速率。

TCP头部

首先介绍一下TCP的头部,TCP的标准头部由20字节构成:

源端口

16bit

标识发送方端口

目的端口

16bit

标识接收方端口

序列号

32bit

本地正在发送的字节在段的位置

确认号

32bit

要求对方发送的字节在段的位置

长度

4bit

TCP头部长度,单位4字节,最多60字节

保留

6bit

全0

特殊位

6bit

URG、ACK、PSH、RST、SYN、FIN

窗口

16bit

CWND,防止本地缓冲区溢出

校验

16bit

检查整个TCP段的完整性

紧急指针

16bit

配合URG,指示紧急字节的段位置

TCP连接建立和拆除

TCP 3-WAY握手

状态\接收

无/超时

SYN

SYN/ACK

ACK

RST

CLOSED

Client发送SYN,打开连接计时器,进入SYN_SEND

/

/

/

/

LISTENEING

Server打开端口侦听

进入SYN_RCV,发送SYN/ACK

/

/

进入CLOSED

SYN_SEND

CLOSED

进入SYN_RCV,发送SYN/ACK

发送ACK,进入ESTABLISHED

/

进入CLOSED

SYN_RCV

/

/

/

进入ESTABLISHED

进入CLOSED

ESTABLISHED

应用程序定义

/

/

/

进入CLOSED

TCP 4-WAY 挥手

状态\接收

无/超时

FIN

ACK

FIN/ACK

ESTABLISHED

发送FIN,进入FIN_WAIT1

发送ACK,进入CLOSE_WAIT

FIN

_WAIT1

发送ACK,进入CLOSING

进入FIN_WAIT2

发送ACK,进入TIME_WAIT

FIN

_WAIT2

发送ACK,进入TIME_WAIT

CLOSING

进入TIME_WAIT

TIME

_WAIT

等待超过2MSL,进入CLOSED

CLOSE

_WAIT

发送FIN,进入LAST_ACK

LAST

_ACK

进入CLOSED

TCP可靠传输

TCP通过3次握手建立连接,4次挥手拆除连接,并通过以下3个机制保障传输的可靠性。这3个机制是:

  • 校验。发送端发送每个数据段都进行校验,接收端校验失败的数据段直接丢弃;
  • 序列号。发送端对每个待发送字节记序列号,并在数据段中表明本段第一个字节的序列号。接收端在接收窗口(RWND)对接收字节进行排序。
  • 连续ARQ。接收端对接收窗口内的字节进行排序,并通过连续ARQ机制,对排序好的字节进行一次性确认。
  • 超时重传。发送端对发送窗口(SWND)内每个数据段计时器。若计时器超时前未收到某一个数据段的确认,将重传该数据段。
  • 滑窗。发送端动态调整发送窗口的大小,使其匹配接收窗口和拥塞控制要求。滑窗不是严格意义上可靠传输的手段,但由于滑窗能够使得发送方不会因为发送过快,而接收方缓存太少导致丢包,宏观意义上也有利于可靠传输。

缓存区与窗口

SBUFF和RBUFF可以看作一个环形FIFO队列。在发送端,发送程序把字节按顺序推入SBUFF指针所在位置,TCP从SWND首部取出字节封装发送;在接收端,TCP把接收到的字节推入RWND尾部,接收程序从RBUFF指针处取出字节。以下以发送端发送“HELLOHOWAREYOU”为例子介绍TCP发送和接收缓存。假设MSS(最大数据段尺寸)= 1 Byte,即每个数据段携带1个字节。

发送缓存SBUFF和发送窗口SWND

SWND是在SBUFF内定义的一个区域。SWND的作用是保留尚未确认的字节准备重发。发送端TCP维护3个指针值,包括SWND首部、SWND尾部、SBUFF指针。SWND内的字节已经或正在发送,但未收到确认的字节;从SWND右侧到SBUFF指针的字节是应用程序推入SBUFF等待发送的字节。

  1. 发送端应用程序把待发送字节加入到SBUFF指针处(即将加入的字节是“YOU”)。
  2. 在收到SWND中部分字节的确认后(这里等待确认的是“HOW”),TCP将SWND内,从SWND首部一直到被确认字节的数据段删除,同时SWND首部和尾部向SBUFF后移。例子中若“HOW”被确认,则SWND内将后移至“ARE”,这里假设SWND大小没有发生变化。
  3. SWND内有新的未发送字节,TCP立即发送发送并等待确认。

接收缓存RBUFF和接收窗口RWND

同样,RWND是RBUFF的一个区域。RWND作用主要有两个:拥塞通知和排序。接收端TCP维护3个指针值,包括RBUFF指针值,RWND首部,RWND尾部。RWND首部记录着第一个未收到字节序列号的下一位,RWND尾部记录着从RBUFF指针到RWND首部的字节是缓存区等待TCP送往接收程序的字节;RWND内的字节是等待排序并发送确认的字节。

  1. 检查RWND内是否有从当前ACK值开始的连续字节,有则后移RWND,直到没有连续已排序字节,更新当前ACK值并适时发送ACK确认。这里“HELLO”已按顺序接收,RWND后移。
  2. 接收端TCP检查RWND的余量,有则接收对应字节数,无则拒绝接收。这里TCP检查RWND余量为3,传入“OW”,并等待接收“H”。
  3. 接收端应用程序从RBUFF指针处接收字节并从RBUFF删除。在这里接收端从RBUFF接收了“H”并从RBUFF中删除。RBUFF指针后移。

一般情况下,只有当接收缓存区满了以后,tcp才一次性提交所有数据到应用层。例外情况是接收到psh字段置1的数据段,这要求tcp立即提交缓存区所有数据。但目前很多实现都不会等到缓存区满才进行提交,而是有则提交,因此该标志用途较少。

TCP确认机制

TCP是面向字节的,采用连续ARQ确认机制,由接收方对收到的字节进行确认,确保传输的完整性。

对于SWND内没有发送的字节,TCP设定重传计时器,然后一次性发送完,然后进行下一步操作:

  • 若收到确认信息,(ack-1)在SWND内,则认为SWND内这一部分的字节均已被完整接收,可以从SWND删除;
  • 若收到确认信息,(ack-1)不在SWND内,则认为该确认是无效的,直接忽略;
  • 若没有收到任何确认信息,SWND内部分字节的重传计时器超时,则重置重传计时器,并重发这部分字节。

接收端需要对接收的所有字节进行确认,但不需要对每一个字节都发送一次确认消息。根据连续ARQ要求,当发送方收到一个字节的确认,即可认为该字节本身和其之前的字节都已经被完整接收;接收端也不需要立即确认收到的字节,RFC建议可延迟不超过0.5s。

拥塞窗口(CWND)

接收窗口余量变小,一是发送端发送速度过快,接收端性能不足;二是由于RWND没完成排序。第一种情况下,接收端一方面在发送确认时,把当前RWND余量作为CWND发送给发送端,由发送端调整使得SWND不大于CWND;另一方面将丢弃新接收的字节,由发送端重传定时器超时后重新发送,并启用慢启动。第二种情况下,接收端在收到非等待字节时立即发送等待字节的确认,发送端收到3个同样的确认后启动快重传和快恢复

TCP拥塞控制

TCP对传输的控制体现在每流和全局两个方面。通过校验码,序列号和确认,TCP确保每流的成功传输。通过拥塞控制,TCP确保在传输路径上的整体效率最大化。

拥塞控制主要实施在发送端,通过2个值和4个机制实现。2个值分别是拥塞窗口CWND,慢启动阈值SSTHRESH;4个机制分别是:慢启动,拥塞避免,快重传,快恢复。以下说明的单位是数据段字节数。

慢启动

发送端在开始发送数据前,首先设置CWND为1,接着按照以下规则计算CWND:

若CWND<SSTHRESH,则每收到1个连续数据段的ACK,CWND+1;

若CWDN>SSTHRESH,则每收到CWND内所有数据段的ACK时,CWND+1。

在CWND<SSTHRESH之前CWND以指数增长,TCP迅速提高发送速率;在CWND>=SSTHRESH,CWND以线性增长,缓慢提高发送速率。

拥塞避免

当重传计时器超时时,发送端设置SSTHRESH=CWND/2,CWND=1

发送端的数据段无法送达或者接收端的ACK无法返回,使发送端TCP认为网络出现了拥塞。这时发送端TCP重新开始慢启动,并更早使CWND进入线性增长。

快重传

当接收端收到了一个非等待的字节时,将立即向发送端发送一个确认,ACK为所等待字节的下一个序列号,请求发送端发送丢失的字节。如果接下来的字节仍然不是所期待的字节,接收端将继续发送相同的确认。

快恢复

当发送端收到3个确认,ACK均为发送窗口的首部Seq,将认为该数据段已经在网络中丢失。发送端将:

  • 立即向接收端重新发送该数据段;
  • SSTHRESH=CWND/2;
  • CWND=SSTHRESH。

由于CWND并没有像拥塞避免一样重新开始慢启动,发送速度只是减半。而且CWND=SSTHRESH,其增长速度为线性增加,降低了网络拥塞的可能性。

全局同步

TCP的拥塞控制虽然单独看起来很完善,但在全局应用中会有很大问题,这就是全局同步(Global Synchronization)。全局同步的含义是,多个TCP流同时慢启动,又同时拥塞避免。

假设在T=0时,一个终端同时对另一个终端发起10个TCP连接。这里不考虑TCP、IP头部消耗,SSTHREST、RWND足够大,MSS=1KB,网络带宽为80KB/s,RTT=2s,重传计时器也是1s。

T=1,CWND均为1,每个TCP流占用1KB/s,流量=10KB/s;

T=2,CWND均为2,每个TCP流占用2KB/s,流量=20KB/s;

T=3,CWND均为4,每个TCP流占用4KB/s,流量=40KB/s;

T=4,CWND均为8,每个TCP流占用8KB/s,流量=80KB/s;

T=5,CWND均为16,每个TCP流占用16KB/s,流量=160KB/s。但带宽只有80KB/s,出现了拥塞。这意味着50%包要被丢弃。这只能由TCP发送端重传计时器超时后重新发送。这里假设所有TCP流都有数据段被丢弃,即所有TCP连接均需要重传。根据拥塞避免,所有TCP流的CWND重置为1。因此:

T=6,CWND均为1,每个TCP流占用1KB/s,流量=10KB/s;

T=7,CWND均为2,每个TCP流占用2KB/s,流量=20KB/s;

T=8,CWND均为4,每个TCP流占用4KB/s,流量=40KB/s;

T=9,CWND均为8,每个TCP流占用8KB/s,流量=80KB/s;

T=10,CWND均为16,每个TCP流占用16KB/s,流量=160KB/s。再一次发生拥塞避免。这个过程将一直循环。

可以看到,全局同步很大程度上将影响网络的传输效率。超过1半时间,网络的利用率都低于50%,还有一些时间网络过载。

目前较为合理应对全局同步的方式,就是在网络中部署RED(随机早期检测/随机早期丢弃),在每个TCP流接近链路总带宽的百分比时,随机丢弃该流的部分数据段。这样可以使TCP进入快重传和快恢复,提早进入线性增长,控制TCP流速率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值