5. 运输层
- 第四层运输层主要是实现了主机之间的通信。
- 数据通信是服务于主机上的进程(Session),主要是进程和进程通讯,而不是主机和主机通讯。
1. 第四层综述
- 第4层执行多项功能:
- 分割上层应用程序数据(新的数据单元-数据段)
- 建立端到端(end to end)的运营
- 从一个终端主机向另一个终端主机发送段(第三层和第二层不进行可靠性检验,第四层完成可靠性检验,接受方认为数据错误,在第四层进行要求重传)
- 流量控制和可靠性
- 可以比喻为与外国人交谈:通常,您会要求外国人重复他/她的话(可靠性)并慢声说话(流量控制)
- 双方主机的网络的处理能力不同,缓存能力不同
- 两个特别重要的第4层协议:
- 传输控制协议(TCP, Transmission Control Protocol)
- 用户数据报协议(UDP, User Datagram Protocol)
- 将传出邮件分成多个部分,在目标站重新组合消息
- TCP: 可靠(效率比较低,早期网络应用少,需要可靠性)
- 面向连接,通讯前三次握手确定链接关系,使用确认机制,提供流量控制
- 软件检查细分
- 重新发送丢失或错误的任何内容
- UDP: 不可靠
- 无连接,不使用确认,不进行流量控制
- 不提供用于细分的软件检查
- 直接丢弃错误的报文,而不进行其他操作
- SCTP(Stream Control Transmission Protocol):流控制传输协议,为了进行视频和音频的传输
1.1. 服务模型
一个主机要区分不同的进程
- TCP和UDP都使用端口(port)来跟踪(track)同时穿越网络的不同会话(用端口号的差别识别不同的进程)
- 应用软件开发人员已同意使用RFC1700中定义的知名端口号
1.1.1. 端口分配规范
占两个字节
- 低于255的端口号(0-255)保留给TCP和UDP公共应用程序使用。(端口号0-255是public的,不可以随意分给其他的进程,如果分发则不符合规范)(如上图)
- 0-1023是熟知端口,有分发的规范,不应当被随意使用
- 1024-49151的端口号进行登记使用,有的是应用程序已经的使用端口号,避免冲突
- 基于端口号的不同,进行不同的包的分发
1.2. 套接字(Socket, 第四层的单位)
socket表示为(IP_address,port),不仅要ip地址,也需要port
- 套接字表示为(IP地址,端口)
- 每个连接都表示为(socket source ,socket destination),这是一个点对点全双工通道
- 通讯被认为是以一个socket和另一个socket之间的连接。(Socket API是一套规范,根据上下文有不同的含义)
- TCP不支持多播和广播
2. TCP (Transmission Control Protocol)
2.1. TCP必须解决的问题
- 可靠传输
- 流传输
- 滑动窗口(窗口进行通信,一次数据传输是有上限发的,缓存问题,拥塞问题)
- 避免拥塞
- 连接控制
- 建立连接:三次握手
- 断开连接:四次握手
2.2. TCP数据段的格式
2.2.1. 首部情况
一行共计4字节,段首在前,固定首部长度为20字节。
2.2.2. 源端口和目的端口
源端口和目的端口字段:各占 2 字节
- 端口是运输层与应用层的服务接口
- 运输层的复用和分用功能都要通过端口才能实现
2.2.3. 序号字段(seq)
序号字段:占 4 字节(4G($2^{32}$)的地址空间)
- TCP 传送的数据流中的每一个字节都编上一个序号
- 序号字段的值指本报文段所发送的数据的第一个字节的序号
- 也就是说,一次连接,最多可以传输2^32^个bit(4G)
- 通过序号字段做可靠传输的保证,指示的是一个TCP传输的bit编码,而不是地址。
- 我们从小向大进行使用,如果使用到最大之后,我们会从小再次重新开始分配。
2.2.4. 确认号字段(ack)
确认号字段:占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号
- 确认对方的数据号(发送同时对上一次传输进行确认)
- 体现出了全双工通信的优点,比如上回收到最后序号是700,那么确认号就是701
2.2.5. 数据偏移
数据偏移(即首部长度):占 4 位
- 指出 TCP 报文段的数据起始处距 TCP 报文段的起始处的长度(Data部分从什么地方开始算)
- 单位是 32 位字(以 4 字节为计算单位)
- 不满足的话使用填充位保证为4字节的整数倍(保证对齐问题)
2.2.6. 保留字段
保留字段:占 6 位,保留为今后使用,目前置 0, 也就是说截止到现在也没有使用这部分的字段。
2.2.7. URG
紧急 URG = 1 时,表明紧急指针字段有效。
- 告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)
- 优先放紧急数据,0 的时候则为不紧急(Ctrl + Z)
2.2.8. ACK
ACK = 1 时确认号字段有效;ACK = 0 时确认号字段无效
通讯的时候基本都是1
2.2.9. PSH(PuSH)
TCP要做很强势的管理工作,TCP可能不会立即传输数据,会根据网络条件自己控制什么时候传,而是会放在缓存里面(收取也是)。要是来不及,尽快相应,就把push位置1,就会立即把缓存里的数据上交。
- 接收 TCP 收到 PSH = 1 的报文段,就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付,此时将缓存所有部分都传输,而并不是只将这个报文段的信息进行传输。
- TCP在正常条件下并不是立马传输的,首先要缓存满了才发送,其次还有就是要保证网络可信的时候才发送
2.2.10. RST
- ReSeT = 1时,表明TCP连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接
- 就是重新来过,如果请求方发送的请求,如果应答方不想连接则将ReSet置为1
2.2.11. SYN
同步 SYN = 1:表示这是一个连接请求或连接接受报文(初始的时候才出现)‘’
2.2.12. FIN(FINis)
用来释放一个连接。FIN = 1 表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。(发送方没有传输数据了)
中止了,我不会主动发数据了。
2.2.13. 窗口
- 占 2 字节,用来让对方设置发送窗口的依据,单位为字节。
- 表示可以进行传输的窗口大小是多少。
2.2.14. 检验和
检验和:占有2字节。
2.2.16. 选项
- TCP 最初只有一种选项,即最大报文段长度 MSS(Maximum Segment Size)
- MSS 告诉对方缓存所能接收的报文段的数据字段的最大长度是 MSS 个字节
- 数据字段加上 TCP 首部才等于整个的 TCP 报文段
2.2.17. 填充字段
填充字段:这是为了使整个首部长度是 4 字节的整数倍。
2.3. TCP协议
- 主机使用网段(TPDU)交换数据
- 每个段都有:
- 首部为20个字节(可选部分除外)
- 0或更多数据字节(请求连接的时候)
- 段的大小必须与IP数据包匹配,并且还必须满足底层的需求
- 例如,以太网的MTU(最大传输单位)为1500字节
- 是面向字节的传输。
- 每个字节都有一个32位序号
- 通讯中商定初识序号,确认到每一位
- 面向字节:TCP传输的数据块和上层数据给的数据块的大小可以不对应(通过商量解决)
- 根据网络条件,对每一个字节进行确认,
2.3.1. Reliable Connection 可靠连接
- 红蓝两军问题
- 两军之间传输信息,要确定计划一起攻打才打得过白军,由侦查员进行传递
- 结论:无论通信多少次,都不能确定一个完全可信的时间。
- 不论怎么设计协议,都达不到绝对可靠的效果。TCP三次握手理论上也不是绝对可靠。
2.3.2. TCP: Establish Connection TCP:建立可靠连接
2.3.2.1. 第一次握手
- 服务器:执行LISTEN和ACCEPT原语,并进行被动监视
- 客户端:执行CONNECT原语,生成SYN = 1和ACK = 0的TCP段,代表连接请求
- 这里的seq是序号
2.3.2.2. 第二次握手
- 服务器检查是否存在监视端口的服务进程
- 如果没有任何进程,请使用RST = 1回答一个TCP段
- 如果存在进程,则决定拒绝或接受请求
- 如果接受连接请求,则发送SYN = 1和ACK = 1的网段
- 这里小写的ack是确认号字段
2.3.2.3. 第三次握手
- 客户端发送一个SYN = 0和ACK = 1的段以确认连接
- 为了避免出现延时之类的情况(如果只有两次会浪费服务器资源,会误解很多发送是请求)
2.3.2.4. 通知上层应用,准备数据传输
服务器收到确认后,会通知上层应用程序
- 默认三次握手就认为可靠了,之后就进行数据传输
- 有时候我们会选择,第三次握手的时候同时携带数据。
2.3.3. 建立连接实例
- 用于连接同步(Synchronization)的基本三次握手
- 请注意,ACK不会占用序列号空间(如果确实如此,我们将结束ACK的ACK!)
2.4. 停止等待协议
- 发送段后,暂时保留备份
- 在发送后没有收到确认的时候,要保存备份来重传
- 收到确认的时候,抛弃备份
- 超时计时器:如果对方的应答超过一定时间后则直接进行重发(时间要比正常往返时间稍微长一点)
- 每个网段和ACK必须具有ID
- 重新发送时间必须大于平均传输时间 * 2(也就是平均往返时间)
- 停止等待协议是一个简单的协议,但是效率很低
- 实施控制,来进行错误处理
2.5. 数据传输 - 丢失确认 和 确认延迟
- 发过去没有应答或者丢失:进行重传
- 应答超时,有收到请求立即重传(即便之前受到过数据了,受到相同的还是会做应答的)
- 晚到的应答直接丢弃(不做处理)
2.6. 可靠通信
ARQ (Automatic Repeat reQuest) 自动重传请求:这表示”重新发送请求”为自动发送并且接收方无需请求发送方重新发送错误段
2.6.1. Contiguous ARQ(Automatic Repeat-reQuest) Protocol 连续ARQ协议
- 多个数据同时发送过去(一次发送多个)
- 窗口大小是双方协商的,通过TCP报文中的窗口字段表示。
2.6.2. ARQ具体实例
- 发送端要发送 900 字节长的数据,划分为 9 个 100 字节长的报文段,而发送窗口确定为 500 字节。
- 发送端只要收到了对方的确认,发送窗口就可前移。
- 发送 TCP 要维护一个指针。每发送一个报文段,指针就向前移动一个报文段的距离。
- 发送端已发送了 400 字节的数据,但只收到对前 200 字节数据的确认,同时窗口大小不变。
- 现在发送端还可发送 300 字节。
- 发送端收到了对方对前 400 字节数据的确认,但如果对方通知发送端必须把窗口减小到 400 字节。
- 现在发送端最多还可发送 400 字节的数据。
- 利用可变窗口大小进行流量控制双方确定的窗口值是 400
- WIN:窗口的大小:双方动态协商,收到确认调整窗口
- ACK:是指可以继续发送的数据的位置。
- 为什么201在401后面发送?超时重传(要超过两倍的平均传输时间后才进行重传)
- 一旦确认了一个序号(比如401),那么就代表这个序号之前的所有数据都收到了(比如201)
2.7. TCP:释放链接
- 发起断开连接请求
- Ack = 1:允许断开,但是此时并不是断开连接,而是说不再发送新的数据,此时我们需要完成之前未处理完成的数据的处理。(这里只是说我已经收到了你请求停止传输的请求)
- FIN = 1:数据处理完成,注意需要的变化(此时表示所有的需要处理的数据已经处理完了,此时表示正式确认断开)
- 确认收到B的断开信息
- 上图是释放连接的汇总
- 等待最大的网路往返时间(保证能处理到B最后发送的报文)
2.8. 为什么必须等待2MSL(2倍最大往返时间)?
- 为了确保A发送的最后一个ACK可以到达B。如果第4次握手B没有收到,B会重新发第3次握手,这个时候A一定要保证可以响应到。
- 防止出现任何无效的连接请求段:等待2 MSL(最大往返时间)之后,我们可以确保连接上的所有段均已消失
2.9. TCP中的计时器
- 重传计时器:多长时间进行重传
- 坚持计时器:避免死锁(WIN被设置为0,后面说修改WIN使其可以发数据了,但是没收到这个消息,所以没有办法发送过去):收到WIN = 0 的时候,开始进行计时,到时间主动询问
- 保持计时器:
- 发送数据段后,刷新
- 如果到达一定的时间,则再次询问是不是还要保持连接。
- 时间等待计时器:就是上图的TIME-WAIT
2.10. TCP的有限状态机
- 粗线:正常的服务器端
- 虚线:正常客户端
- 细线:异常状态的问题
3. 用户数据报协议(UDP, User Datagram Protocol)
3.1. 用户数据报协议UDP (User Datagram Protocol)
- 为什么我们需要UDP?
- 没有建立连接(避免延时)
- 简单:发送方,接收方无连接状态
- 小段标题
- 没有拥塞控制:UDP可以按照期望的速度传输
- 无连接:没有复杂控制,头部简单
- UDP发送方,接收方之间没有握手(HandShake,包含进程等信息的)
- 每个UDP段都独立处理
- 常用于流媒体(Stream)多媒体(multimedia)应用
- 容忍损失:无非就是降低帧率
- 这类应用是速率敏感的应用,而不一定是质量敏感的应用。
- UDP用于:
- RIP:定期发送路由信息(periodically)
- DNS:避免延迟建立TCP连接(DNS需要快速找到)
- SNMP:SNMP:拥塞时(congestion),SNMP必须仍然可运行。在没有拥塞和可靠性控制机制的情况下,UDP在这种情况下的性能要优于TCP。(主播和多播,大量信息传输)
- 其他协议包括TFTP,DHCP
- 必要时增加应用层的可靠性
- 流媒体就算有数据丢失也问题不大(对屏幕进行模糊化处理就行),但是发送速率是很重要的!(就算丢包了,也可以模糊处理)
3.2. UDP数据帧格式
- UDP的数据段很简单
- UDP只有8个字节的首部
- 源端口、目的端口、长度、校验(data)、Data
- 校验也要对data和伪首部一并校验,如果出现错误,直接丢弃。
- 应用层进行数据切片,决定如何进行发送,UDP直接发送
3.3. TCP和UDP的不同
3.3.1. TCP
- 不是立即交给上层校验,而是需要先和对方沟通
- 缓存满了才统一交付。
3.3.2. UDP
- 直接转发报文,保留报文边界
- IP进行划分
- 应用程序会发送比较合适的UDP报文大小进行发送
3.3.3. 共同点
- 校验是相同的。
4. 应用:NAT和PAT
4.1. 什么是NAT?Network Address Translation
- NAT,是在IP数据包头中将一个地址交换为另一个地址的过程
- 网络地址转换
- 是网络地址即将用完的解决方案
- 实际上,NAT用于允许私下寻址的主机访问Internet。
- IP地址耗尽的解决方案之一
- 保留注册(合法)地址
- 连接到Internet时增加灵活性
- RFC 1631 - Network Address Translator (NAT)
4.2. NAT技术是一个简单的概念
- NAT需要一个路由器来实现
- 左侧是一个局域网
- 在NAT 路由器将局部地址 转换成 网络上的地址(双向转换,有一个NAT表)
4.3. NAT的类型
- 静态NAT:固定的内部地址(internal address)到注册地址(registered address)的映射(一开始就写死)
- 动态NAT:映射以先到先得的方式动态进行(不是写死,配一个地址池,地址池里面都是Global IP,通过更新)
- PAT(过载,Port address translation):端口地址转换用于允许许多内部用户共享一个”内部全局”地址(基于Socket映射,而不是IP地址,多个内网主机映射到一个公网地址)
4.4. NAT地址类型
- Inside Local address (内部本地地址):内网IP地址
- Inside Global address (内部全局地址): 注册IP地址, 对外部展示的内部地址
- Outside Global address (外部全局地址):由主机所有者分配的IP地址。通常是注册地址。(对内网而言的外部,是目的地址)
- 三个地址在上面可以看一下
- 内部主机发送报文给网关,网关根据NAT Table进行翻译,转换成内部全局地址,然后进行转发
4.5. 静态NAT的例子
- 这是静态的表
4.6. 动态NAT的例子
- 指定一个地址池
4.7. NAT的优点和缺点
- 优点:由于并非每个内部主机都需要同时进行外部访问,因此您可以使用少量的全局唯一地址池来服务相对大量的私有寻址主机。
- 缺点:一一映射,并没有从根本上解决地址短缺的问题。
- 也就是说,如果专用地址空间为/8,但公用地址为/ 24,则一次只能有254个主机可以访问Internet,主要内网不是同时有很多主机上网,就可以如上操作,进一步降低地址压力(类似并行和穿行的区别)
4.8. PAT的工作原理
socket->socket的映射
- 第一个是IP
- 可以有不同的端口
- 同样的出口IP
4.9. PAT操作
- 也就是我们对端口信息进行了调整
本文由作者按照 CC BY 4.0 进行授权