您的位置:首页 > 理论基础 > 计算机网络

计算机网络-传输层

2016-08-24 12:28 218 查看


用户数据报协议
UDP

UDP数据报的特点

面向数据报
不提供可靠性——并不能保证能否到达目的地
应用程序必须关心
IP
数据报的长度——因为有可能要分片

UDP封装



UDP首部



源端口号字段:发送进程
目的端口号字段:接收进程
UDP
长度字段:
UDP
首部和
UDP
数据的字节长度,最小值为
8
字节(也就是说数据段可以为空)
UDP
校验和字段:覆盖
UDP
首部和
UDP
数据

TCP
端口号和
UDP
端口号是相互独立的——即
TCP
端口号由
TCP
检查,而
UDP
端口号由
UDP
检查


UDP校验和

概念:由发送端计算,然后由接收端验证,其目的是为了发现
UDP
首部和数据在发送端到接收端之间发送的任何改动
TCP
的校验和是必需的,但
UDP
的校验和是可选的
UDP
数据报的长度在检验和计算过程中出现了两次
填充:为了计算校验和——因为
UDP
数据报长度可以为奇数,但校验和的算法以
16-bits
为单位(即校验长度必须为偶数),所以可能要在尾部填充
0



传输控制协议TCP


协议概念

TCP提供一种可靠的面向连接的字节流服务

面向连接

客户端和服务器彼此交换数据之前必须先建立一个
TCP
连接——类似于打电话(先拨号,接通之后再对话)
在一个
TCP
连接中,仅有两方进行通信——这意味着多播和广播不能用于
TCP


可靠

应用数据被分割成合适长度的数据块(报文段或段)发送——
UDP
数据长度可变
超时重传——发送之后启动定时器,若不能及时到达受到确认信息,则重新发送该
TCP
报文
接收端收到报文后会发送一个确认信息
校验和——对首部和数据都进行校验,若数据在传输过程中发送任何变化,都会引起校验和的差错,
TCP
检查出错误后会丢弃这些报文段,并希望发送端进行超时重发
TCP
会对收到的数据重新排序——因为
IP
不能保证数据顺序到达
TCP
丢弃重复的数据——因为
IP
数据报会重复到达
流量控制——
TCP
连接的每一方都有固定大小的缓冲空间,接收端只允许另一端发送接收缓冲区所能接纳的数据

全双工:表示数据能在两个方向上独立的传输——因此连接的每一方必须保持每个方向上的传输数据序号

TCP封装



TCP首部



源端口号字段:源端的端口号——用于寻找发送端的应用程序
目的端口号字段:目的端的端口号——用于寻找接收端的应用程序
序号字段:用于标识该报文段中的字节流的起始位置——即数据序号(可以进行重新排序),还包括初始序号(建立连接时使用,且只有
SYN
标志为
1
时,初始序号才有效)
确认序号字段:表示期望收到的下一个字节的序号——即上一个收到的字节的序号加
1
(只有
ACK
标志为
1
时,确认序号才有效)
首部长度字段:首部的长度(以
4
字节为单位)——需要该字段是因为任选字段的长度是可变的,由于该字段共
4
位,因此有20字节⩽TCP首部长度⩽60字节20字节⩽TCP首部长度⩽60字节

保留位字段:后两位
CWR
ECE
用于实现显示拥塞控制ECN机制

CWR
(拥塞窗口减少标志位):由发送端设置,若为
1
,则表示发送方接收到了接收端发出的设置了
ECE
标志的TCP包,并且通知接收方:发送发已按拥塞控制机制进行了回应(可能减少拥塞窗口)

ECE
(ECN及拥塞通知标志位):由接收端设置若为
1
,则表示在TCP三次握手时一个TCP端是具备ECN功能的,并且表明接收到的TCP包的IP头部的ECN被设置为
11
(即接收端发现了拥塞) ——
用以通知发送方网络上发生了拥塞(若
ECE
置为
1
)。

显示拥塞通知ECN:路由器在出现拥塞时通知TCP。当TCP段传递时,路由器使用IP首部中的2位来记录拥塞,当TCP段到达后,接收方知道报文段是否在某个位置经历过拥塞。然而,需要了解拥塞发生情况的是发送方,而非接收方。因此,接收方使用下一个ACK通知发送方有拥塞发生(
ECE
置为
1
),然后,发送方做出响应(
CWR
置为
1
),缩小自己的拥塞窗口。

标志位(有效位)字段:用于判断
TCP
首部中的对应字段是否有效

URG
:若为
1
,则表示紧急指针字段有效
ACK
:若为
1
,则表示确认序号字段有效
PSH
:若为
1
,则表示接收方应尽快将这个报文段交给应用层
RST
:若为
1
,则表示重新连接
SYN
:同步序号,用于发起一个连接——若为
1
,则表示正在建立连接
FIN
:若为
1
,则表示发送端完成发送任务

窗口大小字段:用于流量控制(表示接收方还能下一次还能接收多少数据,若为
0
,则发送方会停止发送数据,知道窗口大小字段大于
0
为止),初始值确认序号字段指明的值(表示接收端正期望接收的字节),由于该字段占
16
位,因此窗口大小最大为216−1=65535字节216−1=65535字节,且该字段的值可变
校验和字段:对整个
TCP
报文(
TCP
首部和
TCP
数据)进行校验
紧急指针字段:一个正的偏移量,和序号字段中的值相加表示数据最后一个字节的序号
任选字段字段:通常是最长报文大小
MSS

数据字段:

四元组——(源IP地址,源端口号,目的IP地址,目的端口号)(源IP地址,源端口号,目的IP地址,目的端口号)用于识别唯一的一个
TCP
连接

最大报文长度
MSS
:默认的
TCP
最大分段大小是
536
TCP
报文的数据区最大长度)——当一个主机想要把
MSS
设置为一个非默认的值时,
MSS
大小会以一个
TCP
可选项的方式在握手时的
SYN
包中定义。由于最大分段大小被一个
TCP
参数控制,主机可以在接下来的任意分段中改变它,且每个数据流的方向都可以使用不同的
MSS

MTU
MSS
的区别

MTU
IP
数据报的最大长度——包括
IP
首部、
TCP
首部、
TCP
数据区最大长度(
MSS
),超过
MTU
IP
数据包会被分片
MSS
TCP
数据区最大长度,数据区部分超过
MSS
大小的
TCP
报文会被丢弃
MTU=IP首部+TCP首部+MSSMTU=IP首部+TCP首部+MSS

超时重传:
TCP
通告在发送时设置一个定时器来解决这种问题,如果当定时器溢出时还没有收到确认,它就重传数据
往返时间
RTT
:往返时间=发送延迟时间+确认延迟时间往返时间=发送延迟时间+确认延迟时间


TCP连接的建立和终止


TCP建立连接(三次握手)

图示



步骤

客户端发送一个同步报文,该报文标志字段中的
SYN
位置为
1
,设置客户端的初始序列号为
seq=x
,并指明客户端打算连接的服务器端口
服务器返回一个确认报文,该报文标志字段中的
SYN
位和
ACK
位都置为
1
,并设置确认序列号为(设置为
ack=x+1
——客户端的初始序列号加
1
,以对客户端的
SYN
报文段进行确认),服务器的初始序列号为
seq=y

客户端返回一个确认报文,该报文标志字段的
SYN
位置为
1
,且确认序列号置为
ack=y+1
(设置为
ack=y+1
——服务器的初始序列号加
1
,以对服务器的
SYN
报文段进行确认),同时设置客户端的初始序列号为
seq=x+1


报文布局

SYN
位为
1
、序号字段为
x
(发送端 ⟹⟹ 接收端)
SYN
位和
ACK
位都为
1
、序号字段为
y
、确认字段为
x+1
(发送端 ⟸⟸ 接收端)
ACK
位为
1
、序号字段为
x+1
、确认字段为
y+1
(发送端 ⟹⟹ 接收端)

注:传输过程中还包括了通信双方的
MSS
以进行协商

为什么TCP连接需要三次握手,两次不可以吗?:为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

已失效的连接请求报文段产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。


TCP连接终止序列(四次握手)

图示



步骤:首先执行关闭操作的是主动关闭方(可能为客户端,也可能为服务器)

某一端首先执行主动关闭(调用
close
)——发送一个
FIN
分节(表示数据发送完毕)——此时主动关闭方处于
FIN_WAIT_1
状态(等待服务器端的
ACK
FIN

另一端的
TCP
端口接收到
FIN
分节后,返回一个确认信号
ACK
(对接收到的
FIN
进行确认,并将其作为文件结束符放入接收队列中)——此时主动关闭方处于
FIN_WAIT_2
状态(等待服务器端的
FIN
),被动关闭方处于
CLOSE_WAIT
状态(等待应用程序发送
FIN

一段时间后,从接受队列中获得文件结束符的应用程序发送一个自己的
FIN
分节(表示数据接收完毕),并执行被动关闭(调用
close
))——此时主动关闭方处于
TIME_WAIT
状态(等待两个
MSL
的时间
—— 为了处理超时重传),被动关闭方处于
LAST_ACK
状态(等待客户端的最后一个
ACK

主动关闭方发送一个确认信号
ACK
(对接收到的
FIN
进行确认)——之后主动关闭方和被动关闭方都处于
CLOSED
状态

报文布局

FIN
位和
ACK
位都为
1
、序号字段为
x
、确认字段为
y
(主动关闭端 ⟹⟹ 被动关闭端)
ACK
位为
1
、确认字段为
x
(主动关闭端 ⟸⟸ 被动关闭端)
FIN
位为
1
、序号字段为
y
(主动关闭端 ⟸⟸ 被动关闭端)
ACK
位为
1
、确认字段为
y+1
(主动关闭端 ⟹⟹ 被动关闭端)



半关闭状态(
FIN_WAIT_1
FIN_WAIT_2
):
TCP
提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力,接口通过这种方式说明:

我已经完成了数据传送,因此发送一个
FIN
给另一端,但我还想接收另一端发来的数据,直到他给我发来一个
FIN
,之后我将进入
TIME_WAIT
状态

主动关闭的一方不直接进入
CLOSED
状态,而是进入
TIME_WAIT
状态,并且停留两倍的
MSL
时长的原因:这是因为
TCP
是建立在不可靠网络上的可靠的协议。

例子:主动关闭的一方收到被动关闭的一方发出的
FIN
包后,回应
ACK
包,同时进入
TIME_WAIT
状态,但是因为网络原因,主动关闭的一方发送的这个
ACK
包很可能延迟,从而触发被动连接一方重传
FIN
包。极端情况下,这一去一回,就是两倍的
MSL
时长。如果主动关闭的一方跳过
TIME_WAIT
直接进入
CLOSED
,或者在
TIME_WAIT
停留的时长不足两倍的
MSL
,那么当被动关闭的一方早先发出的延迟包到达后,就可能出现类似下面的问题:

旧的
TCP
连接已经不存在了,系统此时只能返回
RST

新的
TCP
连接被建立起来了,延迟包可能干扰新的连接

不管是哪种情况都会让
TCP
不再可靠,所以
TIME_WAIT
状态有存在的必要性。

第二步和第三步不是同步发生的,处于这两步之间的主动关闭方仍在接收数据


TCP数据交互


Nagle算法

目的:尽可能发送大块数据,避免网络中充斥着许多小数据块 —— 为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。
定义:Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段。 所谓小段,指的是小于MSS尺寸的数据块,所谓未被确认,是指一个数据块发送出去后,没有收到对方发送的ACK确认。
规则:

若包长度达到
MSS
,则允许发送
若该包含有
FIN
,则允许发送
若设置了
TCP_NODELAY
选项,则允许发送
若未设置
TCP_CORK
选项,但所有发出去的小数据包(包长度小于
MSS
)均被确认,则允许发送
若上述条件都未满足,但发生了超时(一般为
200ms
),则立即发送


流量控制

TCP协议的滑动窗口具体是怎样控制流量的?
TCP的流量控制和拥塞控制


基本原理

流量控制的定义:TCP利用滑动窗口协议来完成流量控制 —— 即接收方通过告知发送方自己的滑动窗口大小,从而控制发送方的发送速度,以防止发送方发送速度过快。

接收方通过ACK数据报告知发送方自己还能接收多少字节的数据,其基本原理如下:

ACK数据报中通常包含两方面的信息:

确认序列号nn:表示接收方期望接收到的下一字节的序号为nn ——
该nn代表接收方已经接收到了前n−1n−1字节数据,此时如果接收方收到第n+1n+1字节数据而不是第nn字节数据,则接收方会继续发送确认序列号为nn的ACK的。
接收方当前窗口大小mm:表示接收方从序列号nn开始,还能接收mm个字节的数据

假设当前发送方已发送到第xx字节(其中x⩾nx⩾n),则发送方还可以发送的字节数为y=m−(x−n)y=m−(x−n),这就是滑动窗口控制流量的基本原理。

如下图所示,其中确认序列号为n=36n=36,发送端当前已将第x=51x=51个序列号发送出去,而当前接收方的滑动窗口大小为m=55−36m=55−36,因此发送方还能将序号为[52,55][52,55]的数据发送出去。




快发送和慢接收



发送方连续发送
4
个背靠背的数据报文段去填充接收方的窗口,然后停下来等待一个
ACK

接收方先发送一个
ACK
,但通告其窗口大小为
0
,说明接收方已收到所有数据,但这些数据都在接收方的缓冲区中——因为应用程序还没有来得及读取这些数据,此时发送方不能再发送数据。
接收方再发送一个
ACK
(窗口更新),表明接收方现在可以接收另外的
4096
字节的数据,此时发送方可以继续发送数据。


滑动窗口



如上图所示:当前窗口覆盖了从第
4
字节到第
9
字节的区域,表明接收方已经确认了包括第
3
字节在内的数据,且通告窗口大小为
6

当接收方确认数据后,这个窗口不时地向右移动
当左边沿到达右边沿时,发送方将不能继续发送数据
窗口两个边沿的相对运动增加或减少了窗口的大小

窗口合拢:左边沿向右边沿靠近,这种现象发生在数据被发送但未被确认时——表示还可以发送的数据减少了
窗口收缩:右边沿向左边沿靠近
窗口张开:右边沿向右移动,这种现象发生在接收端已经确认数据并释放
TCP
接收缓存时,表示允许发送方发送更多的数据


拥塞控制

拥塞控制的原理和算法


慢启动和拥塞避免(已淘汰)

执行慢启动的条件:如果发送方设置的超时计时器时限已到但还没有收到确认,那么很可能是网络出现了拥塞,致使报文段在网络中的某处被丢弃。这时,TCP马上把拥塞窗口cwndcwnd减小到1,并执行慢开始算法,同时把慢开始门限值ssthreshssthresh减半。

慢启动和拥塞避免算法:对每个连接都维护两个变量——拥塞窗口大小(
cwind
)和慢启动门限(
ssthresh
),当cwind<ssthreshcwind<ssthresh时,使用上述慢启动算法;当cwind>ssthreshcwind>ssthresh时,停止使用慢启动算法,改用拥塞避免算法



慢启动:让拥塞窗口
cwind
较快地增大,每经过一个往返时间
RTT
就把发送方的拥塞窗口
cwind
加倍
拥塞避免:让拥塞窗口
cwind
缓慢地增大——每经过一个往返时间
RTT
就把发送方的拥塞窗口
cwind
1

规则:无论慢启动开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢启动门限
ssthresh
设置为当前出现拥塞时的发送方窗口值的一半(但不能小于
2
),然后重新执行慢启动算法(即把拥塞窗口
cwind
重新设置为
1
,并执行慢启动算法)


快重传和快恢复

快重传和快恢复的基本原理:一条TCP连接有时会因等待重传计时器的超时而空闲较长的时间,慢开始和拥塞避免无法很好的解决这类问题,因此提出了快重传和快恢复的拥塞控制方法。在快重传和快恢复算法中,发送端要求接收方每收到一个失序的报文段后就立即发出重复确认
—— 目的是使发送方及早知道有报文段没有到达对方,这样发送端就可以通过接收端发来的重复确认信息代替自己的超时重传机制来判断是否有网络拥塞发生。



当发送方连续收到三个重复确认(确认序列号相同,表示报文失序,而该序列号对应的报文未能及时到达)时,执行“乘法减小”算法,慢启动门限减半



由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢启动算法,而是执行快恢复算法——即把
cwind
值设置为慢启动门限减半后的值,然后开始执行拥塞避免算法,拥塞窗口
cwind
值线性增大。避免了当网络拥塞不够严重时采用”慢启动”算法而造成过大地减小发送窗口尺寸的现象。


总结


流量控制和拥塞控制的区别

流量控制: 所谓流量控制就是让发送方的发送速率不要太快,使接收方来得及接收 —— 如果发送方把数据发送得过快,接收方可能会来不及接收,这就会造成数据的丢失,利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。
拥塞控制:所谓拥塞控制就是防止过多的数据注入到网络中,使网络中的路由器或链路不致过载。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: