我是靠谱客的博主 顺利方盒,最近开发中收集的这篇文章主要介绍传输层 --- 面向连接的传输TCP一.TCP概述二.TCP报文段结构三.TCP可靠数据传输四.TCP流量控制五.TCP连接管理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

面向连接的传输---TCP

  • 一.TCP概述
  • 二.TCP报文段结构
  • 三.TCP可靠数据传输
  • 四.TCP流量控制
  • 五.TCP连接管理

一.TCP概述

1.TCP服务模型:

在一对通信的进程之间提供一条理想的字节流管道。

2.点到点通信:

仅涉及一对通信进程。

3.全双工:

可以同时双向传输数据。

4.可靠、有序的字节流:

不保留报文边界。

5.需要的机制
①建立连接:

通信双方为本次通信建立数据传输所需的状态(套接字、缓存、变量等)。

②可靠数据传输:

流水线式发送,报文段检错,丢失重传。

③流量控制:

发送方不会令接收方缓存溢出。

在这里插入图片描述

二.TCP报文段结构

在这里插入图片描述
1.TCP头包和数据构成:

TCP和UDP都有一个服务器和客户端的模型,对客户端端口和服务器端口来讲,服务器的端口一定要是被指定的,而客户端的端口可以自己分配给它,也可以由计算机或其他设备随机生成相应的端口号。

①序列号:sequence number 32bits

a.当SYN(flag)=1时,这时一个初始序列号。
b.当SYN=0时,序列号代表的是这段数据中累加后的字节,也就是发送了多少个数据的字节。

②确认号:Acknowledgement number 32bits

a.当ACK(flag)=1时,确认号针对的是接受者所期望获得的下一个序列号是多少。
b.第一个ACK对初始的ISN是有确认的,但是对数据没有回应。

③首部长度(数据偏移):Data offset

数据偏移主要代表的是TCP头包有多大的数量,一般的TCP头包的头数量是20bytes,有options和padding时,最大为60bytes。

④状态位:Flags 9bits

URG:紧急指针字段;
ACK:当ACK为1时,Acknowledgement number字段为1;
PSH:当PSH出现时,它要求接收者需要将接收道德数据尽快地提供给应用;
RST:当发送RST请求时,逻辑上的连接需要复位;
SYN:代表的是同步数据请求,在建立连接时会出现;
FIN:在连接终止时会出现。

状态位还包括了ENC域(exploit congestion notification):包括了CWR和ECE。
当一个IP包的ENC域被路由器设置为11时(CWR和ECE均为1),接收端而非发送端被通知路径上发生了拥塞。ECN使用TCP头部来告知发送端网络正在经历拥塞,并且告知接收端发送端已经收到了接收端发来的拥塞通告,已经降低了发送速率。

⑤接收窗口:window 16bits

Window代表的是接收窗口提示,即可以接收的数据量是多少字节。

⑥校验和

16位校验主要是为了在TCP中对头和数据都进行计算。

⑦紧急数据指针:Urgent 16bits

当flag中的URG置位后,16位的字段就是有意义的,这只是相对于序列号的一个偏移。

⑧选项中的几种选择:Options 变长,最大40字节

a.最大报文长度MSS(Maxium Segment Size),指的是一个TCP报文数据段的最大长度。要尽可能大一些但是又不需要IP拆分。
b.窗口扩大选项。可用于控制传输窗口大小。
c.时间戳。非常有用。可以用于计算往返时间RTT、区分重复报文。因为报文的序号只能是232-1个,所以很容易就重复了,加上时间戳可以进行区分。

Q:为何TCP字段没有length字段,而UDP有length字段?
A:TCP容纳不了一个长度字段,但接收端可以隐含计算出;UDP正好剩个位子容纳UDP长度字段,无须隐含计算。
注:一端发送的协议报文,另外一端一定要有方法知道协议报文的长度,如果没有方法知道,那这个协议一定是一个假的协议!

2.发送序号和确认序号的含义
在这里插入图片描述
①这两个序号是实现可靠数据传输的重要组成部分。由于TCP提供的是字节流传输,每个字节都有一个序号。

②序号:这个序号并不是报文段的序号,而是报文段中第一个数据字节的序号。

③确认序号:前面在介绍可靠传输时,假设数据是单方向传输的,接收方的反馈放在一个单独的ACK分组中发送。但是TCP提供的是全双工通信,A向B发送数据的同时,A可能也在从B接收数据,这种情况下A可以将反馈捎带在它发送给B的报文段中。

④TCP采用累积确认,确认序号用来表示期望从对方接收的下一个字节的序号。

⑤举例说明
在这里插入图片描述

a.主机A向主机B发送仅包含一个字符‘C’的报文段:

  • 发送序号是42,
  • 确认序号是79(对前一次数据的确认)。

b.主机B将字符‘C’回送给主机A:

  • 发送序号为79,
  • 确认序号为43(对收到‘C’的确认)。

c.主机A向主机B发送确认报文段(不包含数据):

  • 确认序号为80(对收到‘C’的确认)。

3.重要的TCP选项
①最大段长度MSS

a.TCP段中可以携带的最大数据字节数;
b.建立连接时,每个主机可声明自己能够接受的MSS,缺省为536字节。

②窗口比例因子window scale

a.建立连接时,双方可以协商一个窗口比例因子;
b.实际接收窗口大小=window size*2^window scale^。

③选择确认SACK

a.最初的TCP协议只使用累积确认;
b.改进的TCP协议引入选择确认,允许接收端指出缺失的数据字节。

1.TCP有两个窗口,一个是滑动窗口,一个是拥塞窗口。WS与滑动窗口相关。通过增加一个因子来扩大默认滑动窗口的值。
2.滑动窗口的定义:收到ACK之前可以连续发送的字节数。

举例说明:某接收端的窗口值假设为10240字节,假设发送端发的包每次都是1024字节大小,那么发送端可以连续发送10个包,而不需要收到接收端的ACK确认。

3.窗口大小占TCP头部16位,也就是窗口值最大能有2^16=65535bytes=64K。
65535字节到底多大?在以前网速没有那么快的情况下是足够使用的,但随着网速的不断提升,65535字节就不够使用了。
因此引入了WS,在TCP的option中增加16位作为滑动窗口因子window scaling。
窗口值*窗口因子=最终的窗口值,但是并不是所有的客户端、服务端都支持窗口因子。

三.TCP可靠数据传输

1.概述
①TCP在不可靠的IP服务上建立可靠的数据传输。

②基本机制:

a.发送端:流水线式发送数据、等待确认、超时重传;
b.接收端:进行差错检测,采用积累确认机制。

③乱序段处理:协议没有明确规定

a.接收端不缓存:可以正常工作,处理简单但效率低;
b.接收端缓存:效率高,但处理复杂。

2.一个高度简化的TCP协议
①仅考虑可靠传输机制,且数据仅在一个方向上传输。

②接收方:

a.确认方式:采用积累确认,仅在正确、按序收到报文段后,更新确认序号;其余情况,重复前一次的确认序号(与GBN类似)。
b.失序报文段处理:缓存失序的报文段(与SR类似)。

③发送方:

a.发送策略:流水线式发送报文段。
b.定时器的使用:仅对最早未确认的报文段使用一个重传定时器(与GBN类似)。
c.重发策略:仅在超时后重发最早未确认的报文段(与SR类似,因为接收端缓存了失序的报文段)。

3.TCP发送方要处理的事件
①收到应用数据:

a.创建并发送TCP报文段;
b.若当前没有定时器在运行(没有已发送、未确认的报文段),启动定时器;
c.如果发送窗口不可用,refuse。

②超时:

a.重传包含最小序号的、未确认的报文段;
b.重启定时器。

③收到ACK:

如果确认序号大于基序号(已发送未确认的最小序号):
a.推进发送窗口(更新基序号);
b.如果发送窗口中还有未确认的报文段,启动定时器,否则终止定时器。

4.TCP发送方状态机
在这里插入图片描述

5.TCP可能的重传场景
在这里插入图片描述
①情形一:ACK丢失

超时、重传。

②情形二:超时设置得太小

重发最早未确认的报文段(序号92),重启定时器。
当ACK(100)到来时,更新基序号为100,对序号为100的段启动定时器。
当ACK(120)到来时,更新基序号为120,终止定时器。对最后一个到来的ACK不做响应。

③情形三:累积ACK减少重传

流水式发送的若干报文段中,若某个报文段的ACK丢失,而其后报文段的ACK在超时前到来,则发送方不会重发丢失了ACK的报文段。

④问题:
a.第二种情形,如果TCP像SR一样,每个报文段使用一个定时器,会怎么样?

只使用一个重传定时器,避免了超时值过小时大量报文段的重发。

b.第三种情形,采用流水式发送和累积确认,可以避免重发哪些报文段?

避免重发某些丢失了ACK的报文段。

6.如何设置超时值
①为什么设置合理的超时值很重要

a.若超时值太小,容易产生不必要的重传;
b.若超时值太大,则丢包恢复的时间太长。

②直观上,超时值应大于RTT,但RTT是变化的。

③如何估计RTT:

a.RTT是变化的,需要实时测量从发出某个报文段到收到其确认报文段之间经过的时间(称为SampleRTT)。
b.由于SampleRTT波动很大,更有意义的是计算其平均值(称EstimatedRTT)。

④平均RTT的估算方法(指数加权移动平均):

a.EstimatedRTT=(1-α)*EstimatedRTT + α* SampleRTT。
b.典型的,α=0.125。

⑤瞬时RTT和平均RTT有很大的偏差:

a.需要在EstimatedRTT上加一个“安全距离”,作为超时值。
b.安全距离的大小与RTT的波动幅度有关。

⑥估算SampleRTT与EstimatedRTT的偏差(称DevRTT):

a.DevRTT=(1-β)*DevRTT + β *|SampleRTT-EstimatedRTT|
b.典型的,β=0.25。

⑦设置重传定时器的超时值:

TimeoutInterval=EstimatedRTT + 4*DevRTT

7.TCP确认的二义性
在这里插入图片描述

①TCP确认的二义性问题:

a.重传的TCP报文段使用与原报文段相同的序号;
b.发送端收到确认后,无法得知是哪个报文段进行的确认。

②二义性确认带来的问题:

对重传报文段测量的SampleRTT,可能不准确。

③解决方法:

a.忽略有二义性的确认,只对一次发送成功的报文段测量SampleRTT,并更新EstimatedRTT;
b.当TCP重传一个段时,停止测量SampleRTT。

8.定时器补偿
①简单忽略重传报文段的问题:

a.重传意味着超时值可能偏小了,需要增大;
b.若简单忽略重传报文段(不更新EstimatedRTT),则超时值也不会更新,超时设置过小的问题没有解决。

②解决方法

a.采用定时器补偿策略,发送方每重传一个报文段,就直接将超时值增大一倍(不依赖于RTT的更新);
b.若联系发生超时事件,超时值呈指数增长(至一个设置的上限值)。

9.Karn算法
Karn算法结合使用RTT估计值和定时器补偿策略确定超时值:

a.使用EstimatedRTT估计初始的超时值;
b.若发生超时,每次重传时对定时器进行补偿,直到成功传输一个报文段为止;
c.若收到上层应用数据、或某个报文段没有重传就被确认了,用最近的EstimatedRTT估计超时值。

10.TCP的接收端
①理论上,接收端只需区分两种情况:

a.收到期待的报文段:发送更新的确认序号;
b.其他情况:重复当前的确认序号。

②为减小通信量,TCP允许接收端推迟确认:

接收端可以在收到若干报文段后,发送一个累积确认的报文段。

③推迟确认带来的问题:

a.若延迟太大,会导致不必要的重传;
b.推迟确认造成RTT估计不准确。

④TCP协议规定:

a.推迟确认的时间最多为500ms;
b.接收方至少每隔一个报文段使用正常方式进行确认。

11.TCP接收端的事件和处理
在这里插入图片描述
12.快速重传
在这里插入图片描述

①仅靠超时重发丢失的报文段,恢复太慢。

②发送方可利用重复ACK检测报文段丢失:

a.发送方通常连续发送许多报文段;
b.若仅有个别报文段丢失,发送方将收到多个重复序号的ACK;
c.多数情况下IP按序交付分组,重复ACK极有可能因丢包产生。

③TCP协议规定:

当发送方收到对同一序号的3次重复确认时,立即重发包含该序号的报文段。

④快速重传:

就是在定时器到期前重发丢失的报文段。

event:ACK received,with ACK field value of y
	if(y>SendBase){   //收到更新的确认号
		SendBase=y
		if(there are currently not-yet-acknowledged segments)
	}
	else{    //收到重复序号的ACK
		increment count of dup ACKs received for y
		if(count of dup ACKs received for y=3){
			resend segment with sequence number y //快速重传
		}
	}

13.小结
①TCP可靠传输的设计要点:

a.流水式发送报文段;
b.缓存失序的报文段;
c.采用累积确认;
d.只对最早未确认的报文段使用一个重传定时器;
e.超时后只重传包含最小序号的、未确认的报文段。

②以上措施可大量减少因ACK丢失、定时器过早超时引起的重传。

③超时值的确定:

基于RTT估计超时值+定时器补偿策略。

④测量RTT:

a.不对重传的报文段测量RTT;
b.不连续使用推迟确认。

⑤快速重传:

收到3次重复确认,重发报文段。

⑥TCP使用GBN还是SR?

Go-Back-N
a.接收方:

  • 使用累积确认;
  • 不缓存失序的分组;
  • 对失序分组发送重复ACK。

b.发送方:

  • 超时后重传从基序号开始的所有分组。

TCP
a.接收方:

  • 使用累积确认;
  • 缓存失序的报文段;
  • 对失序报文段发送重复ACK;
  • 增加了推迟确认。

b.发送方:

  • 超时后仅重传最早未确认的报文段;
  • 增加了快速重传。

SR:
a.接收方:

  • 缓存失序的分组;
  • 单独确认每个正确收到的分组。

b.发送方:

  • 每个分组使用一个定时器;
  • 仅重传未被确认的分组。

修改的TCP:
a.接收方:

  • 缓存失序的报文段;
  • 累计确认;
  • SACK选项头中给出非连续数据块的上下边界。

b.发送方:

  • 只对最早未确认的报文段使用一个定时器;
  • 仅重传接收方缺失的数据;
  • 增加了快速重传。

⑦TCP结合了GBN和SR的优点

a.TCP的差错恢复机制可以看成是GBN和SR的混合体:

  • 定时器的使用:与GBN类似,只对最早未确认的报文段使用一个定时器;
  • 超时重传:与SR类似,只重传缺失的数据。

b.TCP在减小定时器开销和重传开销方面要优于GBN和SR。

四.TCP流量控制

1.TCP的接收端:接收缓存
①接收端TCP将收到的数据放入接收缓存。
②应用进程从接收缓存中读数据。
③进入接收缓存的数据不一定被立即取走、取完。
④如果接收缓存中的数据未及时取走,后续到达的数据可能会因缓存溢出而丢失。
在这里插入图片描述

2.流量控制

发送端TCP通过调节发送速率,不使接收端缓存溢出。

3.为什么GBN/SR不需要流量控制
①GBN和SR均假设:

a.正确、按序到达的分组被立即交付给上层;
b.其占用的缓冲区被立即释放。

②发送方根据确认序号即可知道:

a.哪些分组已被移出接收窗口;
b.接收窗口还可以接受多少分组。

4.为什么UDP不需要流量控制
①UDP不保证交付:

a.接收端UDP将收到的报文载荷放入接收缓存;
b.应用进程每次从接收缓存中读取一个完整的报文载荷;
c.当应用进程消费数据不够快时,接收缓存溢出,报文数据丢失,UDP不负责任。

5.TCP如何进行流量控制
①接收缓存中的可用空间称为接收窗口:

RcvWindow=RcvBuffer-[LastByteRcvd-LastByteRead]

②接收方将RcvWindow放在报头中,向发送方通告接收缓存的可用空间。

③发送方限制未确认的字节数不超过接收窗口的大小,即:

LastByteSent-LastByteAcked ≤ RcvWindow

④特别是,当接收方通告接收窗口为0时,发送方必须停止发送。
在这里插入图片描述
6.非零窗口通告
①发送方/接收方对零窗口的处理:

a.发送方:当接收窗口为0时,发送方必须停止发送;
b.接收方:当接收窗口变为非0时,接收方应通告增大的接收窗口。

②在TCP协议中,触发一次TCP传输需要满足以下三个条件之一:

a.应用程序调用;
b.超时;
c.收到数据/确认。

③对于单向传输中的接收方,只有第三个条件能触发传输。

④当发送方停止发送后,接收方不再收到数据,如何触发接收端发送“非零窗口通告”呢?

TCP协议规定:
a.发送方收到“零窗口通告”后,可以发送“零窗口探测”报文段;
b.从而接收方可以发送包含接收窗口的响应报文段。

7.零窗口探测的实现
①发送端收到零窗口通告时,启动一个坚持定时器;
②定时器超时后,发送端发送一个零窗口探测报文段(序号为上一个段中最后一个字节的序号);
③接收端在响应的报文段中通告当前接收窗口的大小;
④若发送端仍收到零窗口通告,重新启动坚持定时器。

9.糊涂窗口综合症
①当数据的发送速度很快,而消费速度很慢时,零窗口探测的简单实现带来以下问题:

a.接收方不断发送微笑窗口通告;
b.发送方不断发送很小的数据分组;
c.大量带宽被浪费。

②解决方案:

a.接收方启发式策略;
b.发送方启发式策略。

在这里插入图片描述
10.接收方启发式策略
①接收端避免糊涂窗口综合症的策略:

a.通告零窗口之后,仅当窗口大小显著增加之后才发送更新的窗口通告;
b.什么是显著增加:窗口大小达到缓存空间的一半或者一个MSS,取两者的较小值。

②TCP执行该策略的做法:

a.当窗口大小不满足以上策略时,推迟发送确认(但最多推迟500ms,且至少每隔一个报文段使用正常方式进行确认),寄希望于推迟间隔内有更多数据被消费;
b.仅当窗口大小满足以上策略时,才通告新的窗口大小。

11.发送方启发式策略
①发送方避免糊涂窗口综合症的策略:

发送方应集聚足够多的数据再发送,以防止发送太短的报文段。

②问题:发送方应等待多长时间?

a.若等待时间不够,报文段会太短;
b.若等待时间过久,应用程序的时延会太长;
c.更重要的是,TCP不知道应用程序会不会在最近的将来生成更多的数据。

12.小结
①TCP接收端

a.使用显式的窗口通告,告知发送方可用的缓存空间大小;
b.在接收窗口较小时,推迟发送确认;
c.仅当接收窗口显著增加时,通告新的窗口大小。

②TCP发送端

a.确定发送时机;
b.使用接收窗口限制发送的数据量,已发送未确认的字节数不超过接收窗口的大小。

五.TCP连接管理

1.建立TCP连接
建立一条TCP连接需要确定两件事:

a.双方都同意建立连接(知晓另一方想建立连接);
b.初始化连接参数(序号,MSS等)。

2.两次握手建立连接
①在一个不可靠的网络中,总会有一些意外发生:

a.包传输延迟变化很大;
b.存在重传的报文段;
c.存在报文重排序。

②两次握手失败的情况:
在这里插入图片描述

3.TCP三次握手建立连接
在这里插入图片描述
①客户TCP发送SYN报文段(SYN=1,ACK=0)

a.给出客户选择的起始序号x;
b.不包含数据。

②服务器TCP发送SYNACK报文段(SYN=1,ACK=1)(服务器端分配缓存和变量)

a.给出服务器选择的起始序号y;
b.确认客户的起始序号x+1;
c.不包含数据。

③客户发送ACK报文段(SYN=0,ACK=1)(客户端分配缓存和变量)

a.确认服务器的起始序号y+1;
b.可能包含数据。

4.如何选择起始序号
①为什么起始序号不从0开始?

若在不同的时间、在同一对套接字之间建立了连接,则新、旧连接上的序号有重叠,旧连接上重传的报文段会被误以为是新连接上的报文段。

②可以随机选取起始序号吗?

若在不同的时间、在同一对套接字之间建立了连接,且新、旧连接上选择的起始序号x和y相差不大,那么新、旧连接上传输的序号仍然可能重叠。

③结论:必须避免新、旧连接上的序号产生重叠。

5.TCP起始序号的选择
①基于始终的起始序号选取算法

a.每个主机使用一个时钟,以二进制计数器的形式工作,每隔△T时间计数器加1;
b.新建一个连接时,以本地计数器值的最低32位作为起始序号;
c.该方法确保连接的起始序号随时间单调增长。

②△T取较小的值(4微秒)

确保发送序号的增长速度,不会超过起始序号的增长速度。

③使用较长的字节序号(32位):

确保序号回绕的时间远大于分组在网络中的最长寿命。

6.关闭TCP连接
在这里插入图片描述
7.客户/服务器经历的TCP状态序列
在这里插入图片描述
8.SYN洪泛攻击
①TCP实现的问题

a.服务器在收到SYN段后,发送SYNACK段,分配资源;
b.若未收到ACK段,服务器超时后重发SYNACK段;
c.服务器等待一段时间(称SYN超时)后丢弃未完成的连接,SYN超时的典型值为30~120秒。

②SYN洪泛攻击:

a.攻击者采用伪造的源IP地址,向服务器发送大量的SYN段,却不发送ACK段;
b.服务器为维护一个巨大的半连接表耗尽资源,导致无法处理正常客户的连接请求,表现为服务器停止服务DoS。

9.TCP端口扫描
①TCP端口扫描的原理:

a.扫描程序依次与目标机器的各个端口建立TCP连接;
b.根据获得的响应来收集目标机器信息。

②在典型的TCP端口扫描过程中,发送端向目标端口发送SYN报文段:

a.若收到SYNACK段,表明目标端口上有服务在运行;
b.若收到RST段,表明目标端口上没有服务在运行;
c.若什么也没收到,表明路径上有防火墙,有些防火墙会丢弃来自外网的SYN报文段。

③FIN扫描试图绕过防火墙,发送端向目标端口发送FIN报文段:

a.若收到ACK=1、RST=1的TCP段,表明目标端口上没有服务在监听;
b.若没有响应,表明有服务在监听(RFC973的规定);
c.有些系统的实现不符合RFC973规定,如在Microsoft的TCP实现中,总是返回ACK=1、RST=1的TCP段。

最后

以上就是顺利方盒为你收集整理的传输层 --- 面向连接的传输TCP一.TCP概述二.TCP报文段结构三.TCP可靠数据传输四.TCP流量控制五.TCP连接管理的全部内容,希望文章能够帮你解决传输层 --- 面向连接的传输TCP一.TCP概述二.TCP报文段结构三.TCP可靠数据传输四.TCP流量控制五.TCP连接管理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(62)

评论列表共有 0 条评论

立即
投稿
返回
顶部