TCP UDP
TCP和UDP有什么区别?
- 连接方式不同
- TCP是面向连接的传输协议,会在通信双方建立一个通信信道。所以需要进行tcp三次握手之后才能够发送数据,而发送数据完成之后需要进行tcp4次挥手断开连接
- udp是面向无连接的,可以在通信双方直接发送数据
- 可靠性不同。
- TCP是可靠传输,tcp使用一系列机制,比如拥塞处理,滑动窗口,重传等确保发送的数据接收方一定能接收到并且不会发生错码乱码的情况
- UDP是不可靠传输,只会发送数据,但是不保证数据的完整性,也不保证接收方是否接收到数据
- TCP是面向字节流传输的,UDP是面向传输报文的。TCP会将应用层发送过来的数据报文拆分成字节,也正是这一点才能够实现tcp的可靠传输
- tcp的头部远大于UDP,udp的头部只有源端口+目标端口+检验和+长度 8个字节。而tcp不仅有这些还有ack,状态符号,窗口大小等等
- 使用场景不同,udp常用于不需要可靠传输的场景,比如视频语音通话等,而tcp适用于文件传输等
TCP连接如何确保可靠性
TCP是一种面向连接的可靠传输协议。使用一系列机制确保数据传输的可靠性。
- 连接机制。TCP在传输数据之前会进行三次握手确保连接的建立。三次握手的过程可以简化为:客户端发送SYN, 服务器发送SYN-ACK, 客户端发送ACK。然后如果没有数据需要进行传输,就会进行四次挥手断开连接,客户端发送FIN, 服务器发送ACK, 服务器发送FIN,客户端最后返回ACK。
- 差错控制。TCP差错控制就是为了检测是否有报文段 损坏,丢失,乱序。并进行纠错
为了实现差错控制,TCP协议使用序列号,确认应答和校验和的方法。- 校验和:TCP通过首部的校验和字段,判断数据是否有损坏,如果检测到损坏,直接丢弃该数据报
- 序列号:每个TCP数据包都会有一个
Seq
序列号标识数据包的顺序 - ACK:当发送端的数据到达接收端,接收端会返回一个ACK确认应答。如果发送方在一段时间内没有收到ACK,就会重新发送数据
- 重传:TCP协议为了解决数据包丢失的情况,使用重传机制解决。
- 超时重传:发送端发送数据后,会设定一个计时器,如果超过该计时器的时间,发送方还没有收到对方的ACK确认应答报文,就会重发数据
- 快重传:不以时间而驱动,而是已数据驱动。当发送方连续三次收到同一个ACK后,会将对应的数据进行重发。接收方在没有收到期望数据号时,会对之前收到的数据进行ACK。
- 流量控制:TCP使用滑动窗口实现流量控制,确保发送方不会随意发送数据,而是根据接收方实际接收能力控制发送的数据量。
- 窗口:在窗口范围内,发送方即使没有收到AKC,也可以继续发送数据,无需一直等待ACK。并且发送方即使没有收到中间的几个ack,只要收到最后一个ACK就确认之前的数据都已经成功发送了。比如窗口大小为3个tcp报文段,发送方发送了3个tcp报文段:400-499,500-599,600-699.但是直接受到了ACK500和ACK700,即使没有收到ACK600,因为收到了ACK700也意味着700之前的数据都被接收到了
- 发送方的窗口大小由接收方窗口大小而决定。发送方发送的数据大小始终不能超过接收方的窗口大小,否则接收方无法正常接收数据
- 拥塞控制: TCP使用4种拥塞控制机制防止网络数据传输量超载而引起严重延迟现象
发送端的窗口大小取决因素不止接收端的窗口大小,还有拥塞窗口。最终大小取决于两者较小的那一个。一旦发生拥塞,tcp就会减小拥塞窗口的大小,从而减小发送端窗口大小- 慢启动。随着收到每个数据报文的ACK以指数速度增加拥塞窗口大小,直到达到慢启动阈值
- 拥塞避免。窗口大小达到慢启动阈值后就以线性速度增加拥塞窗口大小,直到拥塞被检测到
- 快重传。当发送方连续收到3个重复的ACK,认为数据包丢失了,触发快速重传丢失的数据包。并且进入快恢复状态
- 快恢复。TCP将慢启动阈值设置为之前的一半,拥塞窗口设置为当前的阈值,然后以线性的方式增长拥塞窗口大小
TCP 拥塞控制如何实现的?
TCP使用拥塞窗口控制发送端发送的数据量大小以避免整个网络发生堵塞,也就是之前说的发送端的发送端口不仅仅由接收端滑动窗口决定,还会取决于拥塞窗口的大小。而拥塞窗口的增长也是会经历四个阶段
- 慢启动:拥塞窗口最开始以1启动,也就是一个MSS大小,每次发送端收到ACK,就以指数的形式增加拥塞窗口的大小,直到增加到门限值达到第二个阶段。拥塞避免状态
- 拥塞避免:拥塞窗口达到阈值之后就不再以指数的方式增加,而是以线性的方式增加拥塞窗口大小的值。增长到网络发生堵塞为止。只要发送方没有在规定时间内收到ACK,就认为网络发生了堵塞
- 拥塞发生:
- 超时重传:阈值变为当前拥塞窗口的一半,拥塞窗口重置为初始值,然后开始慢启动
- 快速重传:当发送方收到三次连续的ack时,就会触发快速重传。先重传丢失的数据包。拥塞窗口变为当前窗口的一半,阈值也一样。进入快速恢复状态
- 快速恢复:以线性方式增长拥塞窗口大小
为什么要有拥塞控制,不是已经有了流量控制了吗?
流量控制仅仅作用于接收方和发送发,是一个端到端的机制。核心思想是通过接收端的接受能力,告知发送方发送数据不能超过接收端的能力,以避免接收方的缓存溢出。但是只有流量控制无法解决整个网络的拥塞问题,TCP的拥塞控制作用于整个网络,通过动态的调整发送端的发送速率来适应整个网络的状态。也就是TCP是一个无私的协议,当网络发生堵塞时,会调整自身的发送数据量,避免发送方的数据填满整个网络
TCP流量控制怎么实现的?
TCP流量控制一方面是为了不让发送方收到一段TCP报文的ACK再发送下一段TCP报文导致发送数据延迟太大,太慢。另一方面防止发送方发送数据太快导致接收方的缓冲区容量不够而无法接收更多的数据。
因此TCP使用滑动窗口控制流量。
- 每个TCP报文段的tcp头部都会有一个滑动窗口的大小,该字段可以告知发送方可以发送多少字节的数据而不用等待ACK。这个窗口大小是由接收方的缓冲区剩余大小决定的
- 接收方的窗口大小由缓冲区的剩余空间决定
TCP的Keepalive是什么?TCP的Keeplive和HTTP的Keep-Alive是一个东西吗?
完全不是一个。
HTTP的Keep-Alive是应用层的一个持久化连接机制,而TCP的Keepalive是传输层的保活机制。
HTTP的Keep-Alive是在HTTP1.1默认开启的一个持久化连接,也叫做HTTP长连接,如果没有Keep-Alive,在客户端和服务器进行HTTP请求和HTTP响应时,每次都会开启一个新的TCP连接,那我们都知道TCP连接需要TCP的三次握手建立连接和四次挥手断开连接,如果每次进行HTTP请求和HTTP响应都需要这样的建立请求和断开请求就会耗费大量的资源。HTTP持久化连接就实现了可以在一个tcp连接上发送多个HTTP请求,也可以响应多个HTTP响应。这样就能够大幅度降低建立TCP连接造成的资源开销 延迟等。
HTTP1.1是默认开启了持久化连接,如果不需要持久化链接,需要在表头加上Connection: close. 如果是HTTP1.0想要开启持久化连接,就需要在表头加上Connection:keep-alive, 持久化连接也不是一直连接着,除了客户端或者服务器主动断开连接,还可以在表头设置断开连接的时间和请求的次数,比如keep_alive: time_out=10, max=100
TCP的keepalive是保活机制,是为了检测和清除TCP的死连接,如果连接双方一段时间没有进行数据交互,就从一端发出探测报文,这个探测报文的响应时间会有一个上限,如果超过时间上线还没有收到回应,就会重复发出探测报文,发出探测报文的时间也有上限。超过上线次数还没有响应,就会认为该连接失效,关闭该连接