【网络】TCP/UDP

1.概述

传输层是网络中最重要的部分

⑴TCP和UDP的区别
  • TCP是建立连接的,UDP是无连接的,建立连接,指的是在客户端和服务端维护连接
  • TCP无差错、不丢失、不重复、并且按序到达,而UDP完全继承了IP包的特性,没有保证。
  • TCP是面向字节流的,发送的时候发的是一个没头没尾的流,而UDP继承了IP包,基于数据报的,一个个发,一个个收。
  • TCP具有拥塞控制等特性,UDP只管发发发

2.UDP

⑴UDP结构

UDP的包头除了源端口号和目标端口号就没别的了

⑵UDP的使用场景:
  • 丢包不敏感的应用
  • 不面向连接的功能,可以使得可以承载广播或者多播的协议。例如 DHCP、VXLAN、QUIC 等。
  • 需要处理速度快,时延低,可以容忍少数丢包

3.TCP

⑴TCP的包头格式

在这里插入图片描述

  • 源端口号和目标端口号
  • 序号,解决乱序问题
  • 确认序号,解决不丢包问题
  • 状态位
    • SYN 发起一个连接
    • ACK 回复
    • RST 重新连接
    • FIN 结束连接
  • 窗口大小 流量控制
⑵三次握手

在这里插入图片描述

  • 三次握手过程

    • 一开始A(客户端)和B(服务端)处于CLOSED 状态
    • B开始主动监听某个端口,处于 LISTEN 状态
    • A发起SYN,之后处于SYN-SENT状态
    • B收到后返回SYN,并且ACK A的SYN,处于SYN-RCVD状态
    • 然后A再对B的ACK进行ACK,之后处于ESTABLISHED状态
    • B收到A的ACK之后,处理ESTABLISHED状态
  • 为什么不是两次握手?
    A 和 B 原来建立了连接,做了简单通信后,结束了连接。A 建立连接的时候,请求包重复发了几次,有的请求包绕了一大圈又回来了,B 会认为这也是一个正常的的请求的话,因此建立了连接,然后B就结束不了了。

  • 三次握手沟通TCP包的序号问题
    每个连接都要有不同的序号。这个序号的起始序号是随着时间变化的

⑶四次挥手

在这里插入图片描述

  • 四次挥手过程

    • A发送关闭信息,进入FIN_WAIT_1状态
    • B收到后回复A,进入CLOSE_WAIT状态
    • A收到B的回复,就进入 FIN_WAIT_2 的状态
    • 然后B发送关闭信息,A回复后从从 FIN_WAIT_2 状态结束
    • A 等待2MSL的时间,防止B没有收到ACK然后重新向A发送关闭信息,保证A也有足够的时间ACK
    • 假如超过2MSL的时间B还没有收到ACK而继续向A发送,A如果收到了,就会直接向B发送RST,B也就知道A已经跑了。
  • MSL
    报文最大生存时间(Maximum Segment Lifetime)

  • 为什么要四次挥手
    我感觉是为了保证B在CLOSE_WAIT状态处理完该处理的事情。

A向B发送10这个ACK后,B就可以直接停止了,但是A为什么需要等待2MSL呢?

  • 情况1:

如果B没有收到ACK,就会重新发9,这个时间正好是2MSL

  • 情况2:

比如A和B过了一会又勾搭上了,为了方式老的TCP报文在网络中溜达一圈又来了,所以还得等待2MSL,这2MSL正好是发送和应答的和

⑷TCP状态机

在这里插入图片描述
在这个图中,加黑加粗的部分,是上面说到的主要流程,其中阿拉伯数字的序号,是连接过程中的顺序,而大写中文数字的序号,是连接断开过程中的顺序。加粗的实线是客户端 A 的状态变迁,加粗的虚线是服务端 B 的状态变迁。

⑸累计确认

TCP 协议每一个包都有一个 ID,建立连接的 时候,会商定起始的 ID 是什么,然后按照 ID 一个个发送,接收端不会一个一个的应答,而是说某个 ID之前都已收到。

⑹缓存
  • 发送方让自己的发送窗口最大值 = min(滑动窗口,拥塞窗口)
①发送端缓存

发送端的缓存里是按照包的 ID 一个个排列,分成四个部分

  • 发送了并且已经确认的
  • 发送了并且尚未确认的,如果没有收到 ACK,就重发几次,直到报错
  • 没有发送,但是已经等待发送的
  • 没有发送,并且暂时还不会发送的
②接收端缓存
  • 接受并且确认过的
  • 还没接收,但是马上就能接收的
  • 还没接收,也没法接收的
⑺滑动窗口(rwnd)

顺序问题、丢包问题、流量控制都是通过滑动窗口解决。

在 TCP 里接收端会给发送端报一个窗口的大小,大小等于发送端缓存的第二部分加上第三部分。

在这里插入图片描述
1、2、3 已经发送并确认;4、5、6、7、8、9 都是发送了 还没确认;10、11、12 是还没发出的;13、14、15 是接收方没有空间,不准备发的

在这里插入图片描述
1、2、3、4、5 是已经完成 ACK,但是没读取的;6、7 是等待接收的; 8、9 是已经接收,但是没有 ACK 的。

发送端和接收端当前的状态如下:

  • 1、2、3 没有问题,双方达成了一致。
  • 4、5 接收方说 ACK 了,但是发送方还没收到,有可能丢了,有可能在路上。
  • 6、7、8、9 肯定都发了,但是 8、9 已经到了,但是 6、7 没到,出现了乱序,缓存着但是没办法 ACK。
①丢包问题与顺序问题
  • 超时重传
    每一个发送了,但是没有 ACK 的包,都有设一个定时器, 超过了一定的时间,就重新尝试,这个时间会不断变化(重传一次时间加倍)。问题是超时周期可能相对较长。
  • 快速重传
    当接收方收到一个序号大于下一个所期望的报文段时,就检测 到了数据流中的一个间格,于是发送三个冗余的 ACK,客户端收到后,就在定时器过期之 前,重传丢失的报文段。
    比如接收方发现 6、8、9 都已经接收了,就是 7 没来,那肯定是丢了,于是发送三个 6 的 ACK,要求下一个是 7。客户端收到 3 个,就会发现 7 的确又丢了,不等超时,马上重发。
  • SACK
    这种方式需要在 TCP 头里加一个 SACK 的东西,可以将缓存的地图发送给发送方。例如可以发送 ACK6、SACK8、 SACK9,因此发送方一下子就能看出来是 7 丢了。SACK只是针对失序到达的报文段的。
②流量控制

滑动窗口大小是可以变化的。

接收端的应用一直不读取缓存中的数据,那么接收已确认的部分会增大,等待接收未确认的会变小。从而也影响了发送端窗口变小。

比如我们6接收确认但是没有处理,窗口大小就会减一
在这里插入图片描述
同样,发送端窗口也会减一
在这里插入图片描述

⑻拥塞窗口(cwnd)

拥塞控制是通过拥塞窗口来解决。拥塞窗口 cwnd,是怕把网络塞满。拥塞窗口和 滑动窗口共同控制发送的速度:

LastByteSent - LastByteAcked <= min {cwnd, rwnd}

拥塞控制就是在不堵塞,不丢包的情况下,尽量发挥带宽。

①TCP慢启动、拥塞避免、快速重传,拥塞检测

在这里插入图片描述

  • 慢启动(指数级增长)
  • 拥塞避免(线性增加)
    TCP使用了一个叫慢启动门限(ssthresh,一般是65536字节)的变量,当cwnd超过该值后,慢启动过程结束,进入拥塞避免阶段
  • 快速重传
    当接收端发现丢了一个中间包的时候,发送三次前一个包的 ACK,于是发送端就会快速的重传,不必等待超时再重传。TCP 认为这种情况不严重,因为大部分没丢,只丢了一小部分,cwnd 减半为 cwnd/2,然后 sshthresh = cwnd,当三
    个包返回的时候,cwnd = sshthresh + 3,也就是没有一夜回到解放前,而是还在比较高的值,呈线性增长。
②TCP BBR 拥塞算法

就是通过不断的加快发送速度,将管道填满,但是不要填满中间设备的缓存

4.Nagle算法

通俗点说Nagle算法就是服务端将多个请求合并成一个,发给客户端,为了避免延迟过大,有一个定时器,定时器时间到了,立马将缓冲区的数据发送出去。

Nagle算法是时代的产物,因为当时网络带宽有限。而当前的局域网、广域网的带宽则宽裕得多,目前的TCP/IP协议栈默认将Nagle算法关闭,即通过SO_NODELAY = 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值