《TCP/IP - TCP/UDP》
一:概述
- 由于 IP 的传输是无状态的,IP 提供尽力服务,但并不保证数据可以到达主机。
- 所以,数据的完整性需要更上层的 传输层来保证。TCP和UDP 均属于 传输层。
二:UDP
- 特点
- 不具有可靠性的数据报协议。
- UDP 虽然可以确定发送消息的大小,却不能保证消息的到达。
- 应用场景
- 即时通讯
- 包总量较少通讯
- 广播通信
三:TCP
- 特点
- 面向连接的,可靠的流协议。
- 流即为不间断的数据结构,虽然可以保证发送的顺序,但是还是犹如没有任何间隔的发送给服务端。
- 应用场景
- 对数据完整性有要求的通信。
四:TCP 是通过什么机制实现可靠传输的?
- 确认应答
- 问题
- 发送端在发送数据之后,并不知道发送的数据是否成功到达了接收端。
- 解决方案
- TCP 通过肯定的确认应答ACK(Positive Acknowled-gement)实现可靠的数据传输。
- 如果有确认应答,说明数据已经成功到达对端。反之,则丢失的可能性很大。
- 序列号
- 问题
- 在发送端发送数据时,可能因为 某些原因(网络问题/硬件问题) 导致接收端没有收到信息。
- 这样会导致发送端重复发送,接收端会反复接收同样的数据包(然后抛弃数据包)
- 造成主机的压力,和资源的浪费。
- 解决方案
- 发送端,数据的每一个字节标明编号。
- 接收端,根据首部的序列号和长度,将下一步应该接受的序列号返回。
- 这样,通过序列号和确认应答号,TCP 可以实现可靠传输。
-
- 重发控制
- 定义
- 重发超时指的是在重发数据之前,等待确认应答的时间间隔。
- 如果超过了这个时间,发送端将重发数据。
- 问题
- 由于每个网络和当时发生的情况不一样,所以重发超时的时间是不定的。
- 解决方案
- TCP 会计算数据往返时间和’偏差'。计算超时时间。
- 数据若是重发之后还是没有应答,则会 2/4/…. 指数增长
- 当到达一定次数,则会强制关闭连接。
- 连接管理
- 三次握手 (建立连接)
- 四次挥手 (断开连接)
-
- 发送数据 (分段传输)
- 问题
- 在 TCP 的数据传输中,要规定传输数据的大小,以避免出现发送端发送数据过大导致接收端无法处理的问题。
- 解决方案
- 在建立TCP连接时,发送端和接收端确定数据包大小,我们也可以称为 “最大消息长度” MSS(Max Segment Size)。
- TCP 在传输大数据时,是以MSS进行切割发送,重试也是以MSS为单位。
-
- 窗口控制
- 问题
- 由于TCP使用了分段传输数据,则会导致通信往返时间过长,性能变低。
-
- 解决方案
- 使用缓冲区(Buffer)对请求做统一处理(有点像Redis的管道处理),对多个段进行确认应答,提升整体效率。
-
- 窗口控制下的重发机制
- 在窗口比较大,出现报文丢失的情况下,统一序号的确认应答会被不停的返回。
- 而接收端如果连续三次收到了同一个确认应答,则将会对数据进行重发。
- 这种方法比超时控制更有效,也被称为高速重发控制。
-
- 流量控制
- 问题
- 在特殊条件下的,接收端处于 高负荷/耗时处理 状态,需要进行 流量控制。
- 解决方案
- 接收端向发送端发送自己可以接受的数据的大小。
- 发送端接收信息后,就不会发送超过这个限度大小的数据,这个范围被称作窗口大小。
- 实例
-
- 如图,当接收端收到从3001之后的数据端,既缓冲区已满,暂停接受数据。
- 之后收到窗口的更新通知才会继续发送。
- 但是如果这个通知在传输中丢失,可能导致无法通信。
- 为了解决这个问题,发送端会不时的发送一个 窗口探测,来查看接收端状态。
- 其他
- 拥塞控制等
五:TCP/UDP 首部。
- UDP
-
- 源端口号 (16位),表示发送端端口号。在不需要返回的通信中,源端口号为0。
- 目标端口号 (16位),表示接收端端口号。
- 包长度,保存了UDP首都长度和数据长度之和。(字节)
- 校验和,用于数据的校验。
- TCP
-
- 源端口号 (16位),表示发送端端口号。
- 目标端口号 (16位),表示接收端端口号。
- 序列号 (32位)
- 指发送数据的位置,每发送一次。就累积加一次数据字节大小。
- 序号不会从0,1开始,而是在建立连接时候已随机数作为开始值。
- 建立和断开连接的 SYN和FIN虽然不携带数据,但是也会做为一个字节增加对应的序列号。
- 确认应答号 (32位)
- 指下一次应答应该收的的序列号。
- 也可以说是确认应答-1,发送端收到这个应答就表明这个序号之前的数据被成功接收。
五:三次握手和四次挥手?
- 为什么要三次握手?
- (不准确的)《计算机网络》:防止已失效的连接请求又传送到服务器端,因而产生错误。
- 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。
- 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
- 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认.
- 为什么要四次挥手?
- 建立连接,因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。
- 但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。
- 只有等到我Server端所有的报文都发送完了,我才能发送FIN报文。
- 因此不能一起发送。故需要四步握手。