运输层
运输层和网络层的关系
网络层是主机到主机,端到端的逻辑传输。
运输层是应用到应用,端口到端口的逻辑传输。
先由网络层送到主机,再通过运输层送到对应的端口程序中。
运输层将应用层报文封装成报文段交给网络层
将主机间交付扩展到进程间交付被称为运输层的多路复用和多路分解
UDP提供不可靠服务
- 差错检测
- 数据交付
TCP提供可靠服务
- 流量控制
- 序号
- 确认
- 定时器
- 拥塞控制
多路复用和多路分解
源主机使用多路复用把多个套接字进程的报文发送给目的主机
目的主机使用多路分解把报文发送给多个套接字进程
运输层需要再首部信息加入
- 源端口号
- 目的端口号
通过端口号来区分进程
UDP套接字通过二元组来标识
- 目的端口号
- 目的ip
只要你的目的ip和端口号相同就算你的源ip和端口不一样,也会分解到同一个套接字
TCP通过四元组来标识
- 源ip
- 源端口
- 目的Ip
- 目的端口
这是因为TCP会创建链接,一个TCP进程有一个“欢迎套接字”,用来等待程序过来,然后创建一个新的套接字来进行通信。
如果四元组一致会分解到一个套接字,不一致,会分解到另外的套接字。
web服务器和TCP
现在的计算机有线程的概念,所以TCP链接一般也不会创建多个进程来服务不同的客户端,而是创建多个线程套接字,通过分解到不同的线程套接字来服务多个客户端。
无连接运输:UDP
UDP只提供了运输层最低限度的东西。
- 差错检测
- 复用分解
DNS是使用UDP的一个应用层协议.
UDP存在的意义及优势:
- 关于发送什么数据以及何时发送的应用层控制更为精细。
采用UDP时,只要应用将数据给UDP,UDP就会直接传递给IP网络层。TCP有拥塞控制
和重发机制,但是这样会需要更长的时间。因为实时应用通常要求最小的发送速率,不希望过分的延迟报文段的传送,且能容忍一部分数据丢失,TCP服务模型并不是特别适合这些应用的需要。这些应用使用UDP,并可以再应用层实现所需的,超出UDP的额外功能。 - 无需链接建立
TCP需要三次握手建立链接,UDP不需要。因此没有建立链接的时延。 - 无连接状态
TCP需要再端系统中维护链接状态。此链接状态包括接受和发送缓存,拥塞控制参数以及序号与确认号的参数。UDP一般能支持更多的活跃用户。 - 分组首部开销小
每个TCP报文段首部有20字节,UDP只有8字节
UDP也可以通过应用层实现可靠性传输
。比如chrome的QUIC协议
。
UDP报文段结构
- 首部字段 8字节
- 源端口号 2字节
- 目的端口号 2字节
- 长度 2字节 数据长度
- 校验和 2字节 差错检测
- 数据
UDP校验和
发送方的UDP对报文段中的所有16比特字的和进行反码运算,求和时候遇到的任何溢出都被回卷。得到的结果被放在UDP报文段中的校验和字段。
例子
如果有三个16比特的字:
0110011001100000
0101010101010101
1000111100001100
计算他们的和
0110011001100000
+0101010101010101
=1011101110110101
+1000111100001100
=0100101011000001
这个时候溢出了,把溢出的1加到后面
=0100101011000010
进行反码运输,把1变0,0变1
=1011010100111101
这就变成了校验和。
接收方将三个16比特和校验和加在一起,如果全是1,那么就没问题。如果有0,那么就有差错。
把上面的和加上校验和算一下
0100101011000010
+1011010100111101
=1111111111111111
UDP虽然实现了差错检测
,但是没有差错恢复
。他只是丢弃受损的报文段。其他实现是将受损的报文段交给应用程序并给出警告。
TCP
TCP提供全双工服务
。双方都可以发送数据。
TCP首先建立连接。然后把数据引导到发送缓存
中。从发送缓存中取出数据进行发送。取出的数量受限于最大报文段长度
MSS。MSS一般根据最大链路层帧长度
MTU。以太网和PPP链路层都具有1500MTU。所以MSS的典型值在1460 + 40字节的TCP/IP首部长度。
TCP报文段结构:
- 源端口号 16比特
- 目的端口号 16比特
- 序号 32比特
- 确认号 32比特
- 接收窗口 16比特 用于流量控制
- 首部长度 4比特
- 选项字段 可选变长
- 标志字段 6比特
- ACK用于确认
- RST, SYN, FIN用于连接建立和删除
- 拥塞通告中使用 CWR和ECE字段
- PSH置位标识接收方应立即将数据交给上层
- URG用来指示紧急数据
- 紧急数据指针字段 16比特
- 校验和 16比特
往返时间的估计与超时
估计往返时间
估计一个SampleRTT作为样本,根据SampleRTT取平均值,也就是EstimatedRTT。
EstimatedRTT = (1 - a) * EstimatedRTT + a * SmapleRTT
a的推荐值是0.125。
RTT的偏差用DevRTT表示
DevRTT = (1 - b) * DevRTT + b * |SampleRTT - EstimatedRTT|
b的推荐值是0.25
设置和管理重传超时间隔
超时间隔应该 >= EstimatedRTT。但是也不能大太多
TimeoutInterval = EstimatedRTT + 4 * DevRTT
TCP设置单一的定时器,每当超时一次超时时间会加倍,以免造成网络拥塞。
TCP收到同一个ACK三次,会进行快速重传而不等待定时器超时。
TCP采用的是GBN和SR的混合体。
流量控制
TCP有发送缓存和接收缓存。接收方把数据放入接收缓存,然后读取到应用层。
当发送数据太多,为防止接收缓存装不下,需要控制发送端发送数量。
接收窗口
字段就是这个作用,用来控制接收方还有多少空间。发送方就可以根据这个调整发送数量。
如果接收缓存已经满了。那么发送方依旧会发送1比特的数据。这样才能知道接收方变化后的接收缓存大小。
建立连接
- 第一步:发送一个SYN = 1 Seq = 随机序号
- 第二步:返回一个SYN = 1 Seq = 随机序号 Ack = Seq + 1
- 第三步:SYN = 0 Seq = Ack Ack = Seq + 1 可以携带数据
关闭连接
- 第一步:发送一个FIN = 1
- 第二步:接收一个ACK
- 第三步:接收一个FIN = 1
- 第四步:发送一个ACK
拥塞控制
-
端到端的拥塞控制。网络层不提供支持,端系统观察网络层得到结果。
-
网络辅助的拥塞控制。
-
丢失的报文段表示拥塞,降低发送速率。
-
确认报文段表示顺利,提高发送速率
-
带宽检测,逐步提高发送速率,如果丢失超时就降低然后接着提高。
慢启动
开始速率较小。大概MSS/RTT.
每当收到一个确认,就增加一个MSS。也就是指数级增长,不断翻倍。
何时结束?
- 遇到丢包超时
- 达到一个阈值
结束慢启动进入拥塞避免模式
拥塞避免模式
不再郑家指数级,而是一个一个增长。线性增长