计算机网络 | 传输层
目录
1. 概述
1.1 传输层的意义
传输层是只有(在端系统)主机才有的层次。
网络层提供主机和主机之间的逻辑通信,可以把数据从一个主机传送到另一个主机,但是没有和进程建立联系。
传输层提供进程和进程之间的逻辑通信,就是将进程和收到的数据联系到一起,使数据能够为应用服务
1.2 传输层的两个协议
1.3 传输层的寻址和端口
SAP服务访问点(Service Accessing point)
端口号只用于计算机分辨本地进程,总共有2^16=65536种端口号,端口号有很多种,不能随便使用
1.3.1 常见的应用程序端口号
2. UDP协议
2.1 UDP概述
需要应用层传输过来的数据不要太大,因为UDP一次发送一个完整报文不会分片,否则网络层要符合MTU的要求导致IP数据报分组任务就很重。但是应用层传输过来的数据也不能太小,不然效率较低。
UDP适合一些实时应用,因为实时应用延迟要求高,需要立即响应
首部8B而TCP20B
2.2 UDP首部格式
- 16位源端口号,可有可无,如果希望有回复则填上,如果不希望回复则全0
- 16位目的端口号,一定要有
- 16位UDP长度,UDP用户数据报的整个长度,首部长度8B+数据长度
- 16位UDP检验和,检测整个UDP用户数据报是否有错
2.2.1 UDP的校验位构成
这里的伪首部(伪的是IP首部)只是用来计算检验和的,计算完了就丢弃,可以见下UDP的校验方式
2.2.2 UDP校验方式
- 填上伪首部,源IP地址和目标地址
- 检验和字段,用全0填充
- 数据部分,用全0填充成4B对齐
- 将伪首部,首部和数据部分以2B为单位进行分割,采用二进制反码求和,二进制反码求和运算
- 把求和结果求反码后填入检验和字段
- 去掉伪首部,发送
- 填上伪首部,源IP地址和目标地址
- 将伪首部,首部和数据部分以2B为单位进行分割,采用二进制反码求和
- 如果最后得到结果全1就是没问题,否则丢弃数据报同时报送应用层差错报告
3. TCP协议
3.1 TCP协议的特点
TCP必须要建立连接之后才可以进行数据交换,所以TCP是面向连接(虚连接)
流,流入到进程或从进程流出的字节序列
TCP传输数据是随机切割数据的
3.2 TCP报文段的首部
见上图,可以看到TCP是将数据随机分割后加上TCP头传输的,所以
偏移量就是为了标记一下距离TCP开始多少字节是数据,这里的单位是4B,这个偏移量就是TCP首部长度
字段 | 解析 | 占位 | 单位 |
源端口号 | 进程号 | 2B,16位,65535 | |
目的端口号 | 进程号 | 2B,16位,65535 | |
序号sequences | 为了标记这些随机分割之后的数据,这里把第一个字节的编号当成序号 该发送报文段的数据流的第一个字节的序号 | 4B,32位 | |
确认号acknowledge | 期望收到对方下一个报文段的第一个数据字节的序号。若确认号为N,则证明序号N-1及以前的数据都已经收到 | 4B,32位 | |
数据偏移(首部长度) | TCP报文段的数据起始处到TCP报文段的起始处的距离 | 4位,至少是5(0101) | 单位:4B |
保留 | 6位 | ||
6个控制位 | |||
紧急位URG(urgent) | URG=1时,标明此报文段中有紧急数据,是高优先级的数据,应尽快传送,不用在发送缓存里排队,配合紧急指针字段使用 | 1位 | |
确认位ACK(ACKnowledge) | ACK=1时确认号有效,在连接建立后所有传送的报文段都必须把ACK置1 | 1位 | |
推送位PSH(push) | PSH=1时接收方尽快交付接收应用进程,不用等到接收缓存填满再向上交付 | 1位 | |
复位RST(reset) | RST=1时表明TCP连接中出现严重差错,必须释放连接,然后再重新建立传输链接 | 1位 | |
同步位SYN(synchronization) | SYN=1时表明是一个连接请求/连接接受报文 A->B连接请求 A<-B连接接受 | 1位 | |
终止位FIN(finish) | FIN=1时表明此报文段发送方数据已发完,要求释放连接 | 1位 | |
窗口 | 表示发送本报文段的一方的接收窗口,即现在发送端能允许接收端发送的数据量 比如A->B的确认号ACK是701,同时窗口是1000;那么B->A发送的范围是701-1700 | 2B,16位 | |
检验和 | 检验首部+数据,检验时要加上12B伪首部(伪IP数据报的首部),第四个字段(TCP协议字段)为6 | 2B,16位 | |
紧急指针 | URG=1时才有意义,指出本报文段中紧急数据的字节数。即TCP数据部分0-紧急指针位置是紧急数据 | 2B,16位 | |
选项 | 最大报文段长度MSS、窗口扩大时间戳、选择确认等等字段 | ||
填充 | 使首部长度是4B的整倍数 |
窗口就是接收方告诉发送方,还有多少地方(缓存)可以放数据
紧急指针就是告诉TCP从哪里到哪里是紧急数据
3.2.1 TCP的六个控制位
URG的特点就是让数据在发送缓存插队,URG=1的就会在发送缓存中被提前到第一个传输
就是接收端的URG,将PSH=1的数据尽快接收
注意一下,如果没有PSH,一般都是接收方缓存满了之后再将数据发送到主机。就是在接收缓冲排队,直接接收
A和B主机要建立连接,就A先发一个报文,其中SYN=1
B收到之后也回复一个SYN=1的报文,代表接受连接
3.3 TCP连接管理
3.3.1 TCP三次握手(建立连接)
注释:
第一段的意思是
SYN=1:(A)要建立连接了!连接请求报文段
seq=x(随机):因为还没有数据,所以序号写什么都无所谓
第二段的意思是
SYN=1:我(B)同意你(A)建立连接!连接确认报文段
ACK=1:连接建立了,之后的ACK必须都置为1
seq=y(随机):因为还没有数据,所以序号写什么都无所谓
ack=x+1:之前发送方(A)说发送的是第x位数据(虽然发送方是瞎说的),所以我(B)要的是x+1位数据
第三段的意思是
SYN=0:SYN只有在建立连接时才为1,其他时候均设为0
ACK=1:连接建立了,之后的ACK必须都置为1
seq=x+1:服务端ack是x+1(就是想要客户端发过来),我(A)发送的报文段的第一个字节就是x+1
ack=y+1:之前接收方(B)说发送的是第y位数据(虽然接收方是瞎说的),所以我(A)要的是y+1位数据
注意一下,TCP是双向的,所以不存在绝对不变的发送方接收方,这里的两台主机都同时是发送方和接收方
3.3.2 TCP四次挥手(连接释放)
注释:
第一段的意思是
FIN=1:(A)要释放连接了!
seq=u:发了好多数据,这里只是用u指代一下,这里u是有确定值的
第二段的意思是
ACK=1:连接建立了,之后的ACK必须都置为1
seq=v:发了好多数据,这里只是用v指代一下,这里v是有确定值的
ack=u+1:之前发送方(A)说发送的是第u位数据,所以我(B)要的是u+1位数据(尽管此时A已经决定释放连接了)
第三段的意思是
FIN=1:(B)要释放连接了!
ACK=1:连接建立了,之后的ACK必须都置为1
seq=w:发了好多数据,这里只是用w指代一下,这里w是有确定值的
ack=u+1:之前发送方(A)说发送的是第u位数据,所以我(B)要的是u+1位数据(因为A直接不发数据了,所以第二段第三段的ack都是u+1)
第四段的意思是
ACK=1:连接建立了,之后的ACK必须都置为1
seq=u+1:之前发的数据时第u位数据,B也要第u+1位数据,所以我发第u+1位数据
ack=w+1:之前发送方(B)说发送的是第w位数据,所以我(A)要的是w+1位数据
为什么需要等待计时2MSL(Maximum Segment Lifetime,报文最大生存时间)?
因为这样可以保证B可以收到A的终止报文段进而进入关闭状态
比如说如果A的第四段报文丢失,那么等待一个MSL之后B就会重传第三段报文,花费小于1MSL之后A就会再收到第三段报文,之后就可以再次向B发送第四段报文提示B关闭连接
3.4 TCP可靠传输
可靠传输,保证接收方进程从缓存区读出的字节流与发送方发出的字节流是完全一样的。
TCP是提供可靠传输,UDP这种本身还是不可靠传输的就再靠应用层解决了
校验,在发送方和接收方增加伪IP首部,通过使用二进制反码求和判断有没有发生错误
3.4.1 序号
就是TCP根据下方数据链路层的MTU(最大传输单元)来随即将数据切割成好几端并且进行编号
3.4.2 确认
发送方每一次发送数据之后都需要接收方进行确认。
TCP使用的是累计确认机制,就是从第一个丢失的字节开始请求丢失的报文段。如图中456丢失,78到达,但仍然请求发送的数据序号是4
在有数据要发送时,捎带确认
3.4.3 重传
超时重传和冗余确认
为什么要使用自适应算法?网络环境太复杂,路径又长又短,RTT设置短了照顾不了距离远的,RTT设置长了又导致网络利用率降低,所以使用RTTs(smooth,加权平均往返时间)
收到3个重复的确认,就是3个冗余ack,执行快重传算法
TCP的发送缓存、接收缓存、发送窗口、接收窗口、停等协议、GBN协议、SR协议,相关内容在数据链路层已讲过
3.5 TCP流量控制
rwnd(receiver window)
cwnd(crowded window)
概况起来就是,接收方根据自己接收缓存的大小(接收窗口rwnd),动态调整发送方发送窗口的大小。
接收方接受不过来了就让发送方发送窗口小点,这样发送方发送的速率就慢下来了,接收方就有时间处理它的数据了
接受方处理完了也可以发送请求让发送方发送窗口大点,这样发送方发送的速率就快起来了,接收方就可以处理更多数据而不是空闲等着收数据了
方法是,接收方设置TCP协议中的窗口字段来将rwnd通知发送方。
发送方的发送窗口取接收窗口rwnd和拥塞窗口cwnd的最小值。
3.5.1 计时器
在本例子中,使用的累计确认机制(一次回复收到ack=201)和三次流量控制机制。
但是有一个情况就是,如果最后B不允许A再发送数据了,B在处理完数据之后想要恢复窗口大小时发送的有rwnd大小的数据报丢了怎么办?此时A有B的指令在前,发送窗口为0无法发送数据,B也在等待A回复,造成了类似死锁的现象
解决方法:使用计时器
3.6 TCP拥塞控制
流量控制是对单独一个资源来说的,拥塞控制是一群资源堵塞
流量控制是点对点之间的通信量的问题,是端到端的问题,发送过快导致接收来不及,接收缓存不够和接收窗口不够
3.6.1 拥塞控制四种算法
这里虽然是四种算法,但是通常是两两结合进行使用
接收窗口是接收方根据缓存设置的值,并告知给发送方,反映接收方容量
拥塞窗口是发送方根据自己估算的网络拥塞程度而设置的窗口值,反映网络当前容量(全局性的)
3.6.2 慢开始和拥塞避免
- 横坐标,传输轮次,发送一批报文段并收到它们的确认的时间,一个往返时延RTT
- 纵坐标,拥塞窗口rwnd,单位一个报文段,一个最大报文段长度MSS(Maximum Segment Size)
- 慢开始时cwnd设置为1,以指数形式增长,ssthresh的意思是慢开始门限,代表从这个地方注入的报文段就比较多了,需要开始慢速了。
- 之后一段都是线性增长(加法增大),每次增加1,直至达到网络拥塞状态。
- 瞬间将cwnd设置为1,以指数形式增长,同时调整原来的ssthresh的值到之前达到网络拥塞状态的1/2,(这里是24降到12)
- 之后一段都是线性增长(加法增大),每次增加1,直至达到网络拥塞状态。
重复以上步骤,但是注意此时ssthresh变了之后线性增长的转折点也变了
什么时候拥塞窗口翻倍?当发送方收到之前报文的确认,拥塞窗口就翻倍
3.6.3 快重传和快恢复
这里和上面的慢开始和拥塞避免的一开始步骤差不多,都是先指数增长再转变为线性增长。
不同的点是快重传和快恢复算法是在收到连续的ack确认之后执行,这里的ack就是冗余ack,冗余ack的特点是如果多次对某一段请求的数据没有被收到,达到一定数目(3个)之后就会立即执行重传。但是此时只是降到现在cwnd的一半,再重新线性增长。而不是像慢开始和拥塞避免的从头开始
4. 本章思维导图
本文常用名词中英文对照
Multiplexing and demultiplexing 复用与分用
Positive acknowledgments 肯定确认
Negative acknowledgments 否定确认
Countdown timer (倒数)计时器
Cumulative acknowledgment 累积确认
Receive buffer 接收缓冲区,或接收缓存
Resource-management cells 资源管理单元
Source (port number) 源端口号
Destination (port number) 目的端口号
Checksum 校验和
Pipelined protocols 流水线(型)协议
Go-back-N 回退N
Selective Repeat 选择重传
Timeout (定时器)超时
Fast Retransmit 快速重传
Flow Control 流量控制
Three way handshake 三次握手
sequence number 序列号(简写为seq)
acknowledgement number 确认号(简写为ack;注意与大小的ACK不同)
Congestion Control 拥塞控制
additive increase, multiplicative decrease 加性增乘性减
Slow Start 慢启动
congestion-avoidance 拥塞避免
fast recovery 快速恢复
duplicate (ACK) 冗余(ACK)
Random Early Detection 随机早期检测