文章目录
目录
目录
一 . 传输层
传输层处在网络体系模型中的第四层
1.1 两种传输层协议 TCP&&UDP
在TCP/IP协议栈中能实现传输层功能并且具有代表性的协议是TCP和UDP。
TCP
TCP是面向连接的,可靠的流协议。流就是指不间断的数据结构,可以简单的将其类比为水管中流动的水流。当应用程序使用TCP发送数据时,虽然可以保证发送的顺序,但是考虑到数据在网络中传输的各种不确定性,就像是没有进行任何保障一样。
TCP为了实现可靠传输,通过实行 “顺序控制”,“重传控制”。此外还具备 “流量控制”,“拥塞控制” 等众多功能。
UDP
UDP是不具备可靠传输的数据报协议。它会将所有对细节的控制交给上层的应用进行完成。
二. 端口号
2.1 定义
数据链路层和IP中的地址指的是MAC地址和IP地址, 前者用来标识一段链路中不同的物理主机否则负责表示网络中的主机和路由器。在传输层中也有这样的概念, 那就是端口号, 用来标识同一台计算机中进行网络通信的不同应用程序因此, 它也被称为程序地址。
一台服务器上通常不会只有一个服务程序去运行,如果真是这样,未免太过奢侈!, 为了区分不同的正在运行中的应用程序,传输层协议通过端口号来区分不同的应用程序。并准确的将数据进行传输。
2.2 通过IP地址,端口号,协议号进行通信识别。
仅仅是凭借一个端口号识别某一个通信是远远不够的。
因此TCP/IP通信中常常使用五个信息来识别一个通信,分别是 “源IP地址”,“目的IP地址”,“源端口号”,“目的端口号”,“协议号”。
①和③ 不是一个通信: 源IP不同 其他相同
①和② 不是一个通信: 源端口不同 其他相同
②和③ 不是一个通信: 源端口不同 源IP不同 其他相同
2.3 端口号如何分配
知名端口号: 标准既定的端口号,已经被规定,无法进行分配。 如HTTP使用80端口。
时序分配法(动态分配): 客户端可以自己指定端口号,也可以让操作系统进行动态分配
三 . UDP
UDP(User Datagram Protocal)(用户数据报协议) 不提供复杂的控制机制, 利用IP提供面向无连接的通信服务。实现进程到进程的数据交付和差错检测,这两种是最低限度的运输层服务。
特点:
面向无连接, 基于数据报,差错检测, 全双工。
应用
- 包总量较少的通信(DNS,SNMP等)
- 视频, 音频等所媒体通信(即使通信)
- 广播通信(广播, 多播)
协议格式
- 源端口号: 表示发送端端口号, 字段长16位。该字段是可选项, 不选即为0
- 目标端口号: 表示接收端端口号, 字段长度16位
- 包长度: UDP数据包的长度(最大为64KB)
- 校验和: 用于校验UDP首部和数据是否出错
四 . TCP(重点)
TCP和UDP的区别相当大。 它充分地实现了传输时的各种控制功能, 可以进行丢包时的重发控制,还可以对没有按序抵达的数据进行顺序控制。此外,TCP作为一种面向连接的协议只有在确认对端存在时才会发送数据,从而可以控制网络流量的浪费。
特点
面向连接 可靠传输 字节流 全双工
可靠传输的实现(重点)
TCP通过序列号,确认应答,重发控制,连接管理以及窗口控制等机制实现可靠传输。
序列号&&确认应答
在TCP中,当发送端的数据到达对端时,对端会返回一个对已收到消息的通知,这个通知就是确认应答。在日常生活中,两个人如果进行网络聊天,不考虑对方没有看到的情况,如果你给对方发送了一个消息,那么对方是会给你返回一个响应的,在网络中同样如此,为了让发送端得知接收端已经收到了消息,接收端就会给发送端回一个消息,这个消息就是确认应答(ACK)。
如果在上述过程中,主机A没有收到来自主机B的一个响应(ACK),那么有很大的可能是主机B发出的ACK在网络传输的过程中丢失了。还有一种可能就是主机B根本没有收到主机A发送来的消息,这种情况就是数据在传输的过程中发生了丢失。
数据丢失
丢失ACK
为了应对这种消息丢失的情况,TCP引入了重发控制(重新发送数据)(后面说)来实现消息的可靠传输。
序列号
再来考虑一下上面数据丢失的情况,对于发送端主机来说,只需要按照重传机制进行数据重传即可,但是对于目标主机来说,这就是一种“灾难”,为什么这么说呢? 因为目标主机会反复的收到相同的数据, 目标主机如果无法区分这些数据是不是已经接受过了的话,那这可就是真的灾难了,为此,就必须引入一种机制,它可以识别是否已经接受过该数据。
上述这些确认应答处理,重发控制以及重复控制等都可以通过序列号来进行解决。
序列号是按顺序给发送数据的每一个字节都标上编号,接收端会查询接收数据TCP首部中的序列号和数据的长度,将自己下一个应该接收的序列号作为确认应答号发送出去,这样,通过序列号和确认应答号,TCP可以实现可靠传输。
连接管理
连接建立(三报文握手 )
假设运行在一台服务器上的主机(客户)上的一个进程想与另一台主机(服务器)的一个进程建立一条连接。客户端应用进程首先会通知TCP,它想要建立一个与服务器上某个进程之间的连接,这就是连接建立。
- 第一次握手
- A 发送同步报文段(SYN) 请求建立连接。
- A进入SYN-SENT(同步已发送)状态。
- 第二次握手
- B 监听到连接请求, 向 A 发送针对 SYN 的确认 ACK, 同时 B 也发送自己的请求建立连接(SYN) 。
- B进入SYN-RCVD (同步收到)状态
- 第三次握手
- A 收到 B 发出的 SYN,给出确认应答 ACK。
- A 收到确认后进入 ESTABLISHED (己建立连接)状态。B 收 到 A 的确认后,也进入ESTABLISHED状态
TCP为什么要三次握手而不是两次
1. 网络延迟导致服务端建立连接,而客户端没建立连接
2. 如果服务端的ACK丢失,会导致客户端一直重试,服务端会连接大量无效连接
当服务端的确认应答 ACK 总是丢失时, 客户端以为服务端没有连接, 它将会不断地重新请求连接,而服务端会连接大量的无效连接, 给服务器增加维护成本, 服务器很容易受到 SYN 洪水攻击。
SYN洪泛攻击
TCP的连接管理为经典的Dos攻击 SYN洪泛攻击 (SYN flood attack) 提供了环境,在这种攻击中,攻击者发送大量的TCP SYN 报文段,而不是完成三次握手的步骤。随着这种SYN纷至沓来,服务器会不断为这些半开连接分配资源,导致服务器的连接资源被耗尽。
- 当服务器收到一个SYN连接报文段时,它并不知道该报文段是来自合法的用户还是SYN洪泛攻击的一部分。 因此服务器不会为该报文段生成半开连接,而是使用一个加密函数生成一个序列号 “cookie” 返回发送方。
- 如果客户是合法的, 则它会返回一个ACK报文段。 当服务器收到该ACK,会进行cookie的验证,如果结果合法的话,服务器就会生成一个TCP连接。
- 如果客户没有返回一个ACK, 则初始的SYN也没有对服务器造成危害,因为服务器并没有为它分配任何资源。
连接关闭(四报文挥手)
- 第一次挥手
- 当主机 A 发送数据完毕后, 发送 FIN 结束报文段。
- 第二次挥手
- 主机 B 收到 段后, 向主FIN 报文机 A 发送一个确认序号 ACK(为防止这段时间内, 对方重传 FIN 报文段) 。
- 第三次挥手
- 主机 B 准备关闭连接, 向主机 A 发送一个 FIN 结束报文段。
- 第四次挥手
- 主机 A 收到 FIN 结束报文段后, 进入 TIME_WAIT 状态。 并向主机 B 发送一个ACK 表示连接彻底释放。
TIME-WAIT可不可以取消?
不可以取消,防止第四次挥手时发送的ACK丢失,导致服务端无法正常进行关闭。
利用滑动窗口控制提高发送速率
在建立TCP连接的同时,也可以确定发送数据包的单位,也可以称之为“最大消息长度” (MSS,Maximum Segment Size)MSS通常根据最初确定的由本地发送主机发送的最大链路层帧长度(即所谓的最大传输单元 MTU)来设置 。 最理想的情况是,最大消息长度是不会被IP做分片处理的最大消息长度。
MSS是在建立连接时,在两端计算机之间被计算得到的。两端计算机在发出建立连接请求时,会在TCP首部中写入MSS选项。
TCP以一个段为单位,每发一个段进行一次消息的确认应答处理,但是如果一次往返时间很长,网络的吞吐量就会很差!
为了解决这个问题,TCP引入了窗口这个概念。 即使在往返时间较长的情况下, 它也能控制网络性能的下降
窗口大小就是无需等待确认应答就可以继续发送数据的最大值。
流程如下
图中白色部分就是窗口,在窗口范围内的数据即使没有收到确认应答也可以发送出去。 此外,如果发送的数据丢失,发送发需要进行重发,所以,发送方主机在收到对应的确认应答之前,必须在窗口中保留这部分数据。
在收到确认应答的情况下,窗口就可以移动到确认应答所对应的序列号所在的位置。这就是滑动窗口机制。
高速重发控制
在使用窗口控制中,考虑一下消息丢失的情况,如果是ACK丢失了,问题不大,可以通过下一个ACK来进行确认,但如果是数据丢失了,正常情况下发送放需要等待重传时间进行数据重传。
为了提高效率,引入了高速重发控制: 默认收到三个相同的ACK时,表名该报文段丢失, 不必等待超时重传, 可以立即重传 。
流量控制
一条TCP的连接的每一侧主机都会为该连接设置接收缓存。如果TCP连接接收到正确,按序的字节后,它就会将数据放入接收缓存。与之相关联的进程会从该缓存中读取数据,但不必是数据一到达就立即读取。事实上,接收方应用可能正在处理其他事情,如果这个时候发送放不加节制的持续进行数据的发送,不难预料缓存可能会出现溢出的情况。
为了防止这种情况发生, TCP为它的应用程序提供了流量控制服务,用来消除发送方使接收方溢出的可能性。
TCP通过让发送方维护一个接收窗口(窗口大小)的变量来提供流量控制。接收窗口用于给发送方一个提示-该接收方还有多少可用的缓存空间。
流量控制图解
拥塞控制
上面的流量控制是考虑的发送和和接收方主机之间的通信能力, 没有考虑到数据在网络中传输的情况, 如果网络十分拥塞, 而发送发还是按照原来的窗口大小进行发送数据, 无疑会产生丢包问题, 情况严重的话, 网络直接瘫痪!!
为了调节发送方要发送的数据量, 定义了一个叫“拥塞窗口” 这样的概念
实际上的发送窗口大小 = Math.min(拥塞窗口, 接收端主机通知的窗口大小)
那么问题来了, TCP到底是如何计算拥塞窗口大小的呢?
拥塞控制算法
慢开始
慢开始(Slow Start)是TCP拥塞控制算法中的一种机制,用于在连接刚建立或者在网络中出现拥塞时,控制发送端的发送速率,避免导致网络拥塞恶化。
- 初始时,拥塞窗口大小为1个报文段的大小(通常为MSS,最大报文段长度)。
- 每经过一个往返时间(RTT),拥塞窗口大小加倍。
- 当拥塞窗口大小达到一定阈值(慢开始门限),就会进入拥塞避免阶段。
拥塞避免
- 当拥塞窗口大小达到慢开始门限时,进入拥塞避免阶段。
- 在拥塞避免阶段,每经过一个往返时间(RTT),拥塞窗口大小线性增加,即每经过一个RTT,拥塞窗口大小加1。
- 如果发生丢包事件(超时或接收到重复的冗余ACK),将慢开始门限设置为当前拥塞窗口大小的一半,并将拥塞窗口大小重新设置为1,然后重新开始慢开始算法。
慢开始门限(Slow Start Threshold)
快重传
快重传的原理是当发送端接收到连续三个重复的确认(Duplicate ACK)时, 就知道现在只丢失了个别的报文段, 于是不启动慢开始算法, 改为快重传
- 发送端发送报文段并启动定时器等待确认。
- 如果接收端收到乱序的报文段,会发送一个重复的确认。
- 当发送端连续收到三个重复的确认时,立即重传丢失的报文段。
- 在重传后,发送端继续正常的拥塞控制算法(如拥塞避免)。
快恢复
快恢复的原理是在发送端收到第一个重复的确认(Duplicate ACK)时,将拥塞窗口大小减半,然后进入快恢复状态。在快恢复状态下,发送端继续以每收到一个重复的确认就将拥塞窗口大小加1,最终,当对丢失报文的ACK到达时,TCP在降低cwnd后进入拥塞避免。
- 发送端发送报文段并启动定时器等待确认。
- 如果接收端收到乱序的报文段,会发送一个重复的确认。
- 当发送端收到第一个重复的确认时,将拥塞窗口大小减半,并进入快恢复状态。
- 在快恢复状态下,每收到一个重复的确认,将拥塞窗口大小加1,直到达到慢开始门限为止。
- 当拥塞窗口大小达到慢开始门限时,发送端进入拥塞避免状态继续发送数据。
协议格式
- 源端口号(16 bits):标识发送端口号
- 目的端口号(16 bits):标识接收端口号。
- 序列号(32 bits):用于对数据包进行排序和重组。
- 确认号(32 bits):表示期望接收的下一个字节的序列号。
- 数据偏移(4 bits):指示TCP头部的长度。
保留(6 bits):保留字段,用于将来的扩展。控制位(6 bits):包括URG、ACK、PSH、RST、SYN、FIN等标志位。- 窗口大小(16 bits):接收端的接收窗口大小,用于流量控制。
- 校验和(16 bits):用于检验TCP头部和数据的完整性。
紧急指针(16 bits):仅在URG标志位被设置时有效,指示紧急数据的位置。- 选项(可变长度):包括最大报文段长度、时间戳、窗口扩大因子等选项
五. 拓展
Nagle算法
TCP中为了提高网络的利用率, 经常使用一个叫做Nagle的算法。
该算法是指发送端即使还有应该要发送的数据,但是如果这部分数据很少的话, 则进行延迟发送的一种处理机制。具体来说, 就是仅在下列任意一种条件下才可以发送数据,如果都不满足, 则延迟发送。
- 已发送的数据都已经收到确认应答时
- 可以发送最大长度(MSS)的数据时
根据这个算法虽然网络利用率可以提高, 但是会产生延迟。 为此, 在窗口系统以及机械控制等领域中使用TCP时,禁用该算法。
延迟确认应答
实际上, 大可不必为每一个数据段都进行一次确认应答。 TCP采用滑动窗口机制,即使少一些ACK,也问题不大!
捎带应答
捎带应答(Piggybacking)是一种优化网络通信的技术,通常用于减少网络传输中的额外开销和提高网络利用率。在TCP通信中,捎带应答指的是在发送数据的同时,将确认信息(ACK)捎带在数据包中一起发送,而不是单独发送确认信息。
具体来说,当接收端收到数据包后,如果有需要发送的确认信息,通常会将确认信息放入接收缓冲区,并等待一定时间后再发送确认信息。但是,如果接收端有数据要发送给发送端,可以利用这个时机将确认信息捎带在数据包中一起发送。这样,可以减少额外的确认信息传输,提高网络利用率。
总结
以上就是这篇博客的主要内容了,大家多多理解,下一篇博客见!