UDP与TCP详细介绍

UDP协议

UDP 包头格式

UDP包头:源端口号、目标端口号、长度、校验和、数据。

图片说明

UDP 的三大使用场景

  1. 需要资源少,在网络情况比较好的内网,或者对于丢包不敏感的应用
  2. 第二,不需要一对一沟通,建立连接,而是可以广播的应用
  3. 第三,需要处理速度快,时延低,可以容忍少数丢包,即便网络拥塞,UDP依然保持发送速度,而TCP的拥塞控制策略会降低发送速度,这使用户更卡。
  4. 实际使用场景
    1. 网页或者 APP 的访问(HTTP3)QUIC协议(Quick UDP Internet Connections 快速 UDP 互联网连接)是 Google 提出的基于 UDP 改进的通信协议,其目的是降低网络通信的延迟,提供更好的用户互动体验。
    2. 流媒体的协议(直播领域) :TCP 协议在网络不好时会主动降低发送速度,这对本来就卡的看直播来讲是是不能接受的,应该应用层马上重传,而不是主动让步。因而,很多直播应用,都基于 UDP 实现了自己的视频传输协议。
    3. 实时游戏(游戏领域):在游戏中如果出现一个数据包丢失,客户端所有事情都需要停下来等待这个数据包重发,然而玩家并不那么关心过期的数据,团战中多卡一秒都可能会死。对实时要求较为严格的游戏,会采用自定义的可靠 UDP 协议,自定义重传策略,把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成的影响。

TCP协议

TCP 包头格式

TCP 包头:源端口号、目标端口号、序号seq、确认序号ack、首部长度、状态位、窗口大小rwnd、校验和、紧急指针、选项

  1. 确认序号ack:我想要收到的下一个序号
  2. 首部长度:就是TCP头的长度
  3. 保留:6位,没有意义,说不定以后的时代会将保留位更改为有意义的位置。
  4. 状态位
    1. 确认标志位ACK:置为1时表明连接状态,0时无效。连接建立后ACK必须置为1
    2. 同步标志位SYN:置为1表明是连接请求报文段,此时不能携带数据
    3. 终止标志位FIN:置为1时表明该主机要释放TCP连接
    4. 复位标志位RST:置为1时表明TCP连接出现异常,需要释放连接重新建立连接
    5. 推送标志位PSH:置为1时,接收方收到会将接受缓存中报文全部上交应用进程,不再等待接受缓存填满。
    6. 紧急标志位URG:置为1时紧急指针有效,0时无效。
  5. 窗口大小rwnd:接收方的接受窗口大小
  6. 校验和:用来检查TCP报文是否出现误码
  7. 紧急指针:表示数据中前n位为紧急数据,发送方会将紧急数据插在发送缓存的最前面立刻封装一个报文发送,接收方则会立刻将紧急数据上交应用进程
  8. 选项:最大40字节,可用来增加TCP功能

图片说明

TCP连接建立
  1. 客户端和服务端一开始都处于 关闭 状态
  2. 服务端开始 监听 某个端口
  3. 客户端发送TCP连接请求报文段,客户端就进入 同步已发送 状态了(报文首部中 同步状态位SYN=1 序号seq=x)
  4. 服务器收到TCP连接请求报文段后,发送TCP连接请求确认报文段,服务端就进入 同步已接收 状态了(报文首部中 同步状态位SYN=1 确认状态位ACK=1 序号seq=y 确认序号ack=x+1)
  5. 客户端收到TCP连接请求确认报文段后,进入 连接已建立 状态,发送一个普通的TCP确认报文段(报文首部中确认状态位ACK=1 序号seq=x+1 确认序号ack=y+1)
  6. 客户端收到TCP确认报文段后也进入连接已建立状态
  • 为什么是三次握手?
    • 正因为是三次握手,对于客户端和服务端来说他们都经历了至少一收一发,就确定对方可以收到自己的消息了,这就保证了两端都可以正常收发消息
    • 如果是两次握手,不仅服务端不能确认对方能不能收到自己的消息,而且还可能导致释放连接后服务端又收到了失效的连接请求,就进入 连接已建立 状态无法退出,很耗资源。
    • 如果是四次握手,那就造成了浪费,因为三次握手已经可以保证两端都可以正常收发消息了

图片说明

TCP连接释放
  1. 客户端和服务端都处于 连接已建立 状态
  2. 客户端发送TCP连接释放报文段,客户端进入 终止等待1 状态(报文首部 终止状态位FIN=1 确认状态位ACK=1 序号seq=u 确认序号ack=v)
  3. 服务端收到TCP连接释放报文段,发送一个普通确认报文段,服务端进入 关闭等待 状态(报文首部 确认状态位ACK=1 序号seq=v 确认序号ack=u+1,)
  4. 客户端收到普通确认报文段后进入 终止等待2 状态,此时 客户端->服务端 这个方向的连接就释放了,但服务端仍然可以向客户端发送数据
  5. 服务端没有数据发送后,发送TCP连接释放报文段,服务端进入 最后确认 状态(报文首部 终止状态位FIN=1 确认状态位ACK=1 序号seq=w 确认序号ack=u+1)
  6. 客户端收到TCP连接释放报文段后发送普通确认报文段,并进入2MSL时间的等待然后进入 关闭 状态(报文首部 确认状态位ACK=1 序号seq=u+1 确认序号ack=w+1)
  7. 服务端收到普通确认报文段后进入关闭状态
  • 第四次挥手为什么要等待2MSL?
    1. 保证服务端可以接收到最后一个普通确认报文段从而关闭,否则如果客户端不等2MSL直接关闭,那么如果服务端没有收到普通确认报文段就会一直重传TCP连接释放报文段,卡在最终确认状态没法关闭
    2. 2MSL时间可以使本次连接中产生的所有报文段都从网络中消失,这样就可以使下一个TCP连接中不会出现旧连接中的报文段

图片说明

TCP的可靠性保证

TCP基于以字节为单位的滑动窗口来实现可靠传输

  1. 待发送字节流分为4个部分:已发送已确认的部分、已发送未确认的部分、未发送可发送的部分、未发送不可发送的部分

    发送窗口由第2第3部分组成,且会根据TCP确认报文段中的确认序号ack和窗口大小rwnd沿待发送字节流向后滑动

  2. 待接收字节流分为4个部分:已交付上层的部分、已接收未交付上层的部分、可接收的部分,不可接收的部分

    接收窗口就是可接受部分,当接收方处理不过来的时候接收窗口就会减小,这就是流量控制

  3. 累计确认就是接收方表示确认序号ack之前的数据都已经接收

  4. 顺序问题:发生顺序问题时一般做法是在接收窗口中保留不按序到达的数据,等待缺失的字节收到后再按序交付上层

  5. 丢包问题

    1. 第一种解决方法是超时重传,发送窗口中已发送未确认的数据迟迟未确认就会触发超时重传,并重新启动重传计时器
    2. 第二种解决方法是快重传,接收方如果发现丢包了,那就发送3个重复的确认报文段,发送方收到后立马重传对应的数据包
    3. 第三种解决方法是SACK选项,接收方在确认报文段中会报告最近接收的不连续的数据块,那发送方就会重传丢的包

  6. 流量控制:就是让发送方的发送速度不能太快,让接收方来得及接收,这是利用滑动窗口机制实现的。缓存区域存放的都是基于字节流的数据,当接收方处理不过来的时候就要减小接收窗口的大小,甚至设置为0。接收窗口不为0后,接收方会发一个报文通知发送方,为防止死锁,发送方也会启用一个定时器,每隔一段时间确认一遍接收窗口的大小是否改变。

  7. 拥塞控制:如果网络非常拥堵,此时再发送的报文段超过了最大生存时间也到达不了接收方,就会产生丢包问题。为此TCP协议引入了慢开始、拥塞避免、快重传、快恢复这四种拥塞控制算法。

    1. 当拥塞窗口cwnd小于慢开始门限ssthresh时,采用慢开始算法,即发送方每收到一个对新报文段的确认就将拥塞窗口+1,相当于每一传输轮次若没出现拥塞则将拥塞窗口大小扩大为两倍当拥塞窗口cwnd大于慢开始门限ssthresh时,采用拥塞避免算法,每一传输轮次若没出现拥塞则将拥塞窗口+1当发生拥塞即超时重传时,将慢开始门限更新为拥塞窗口的一半,并将拥塞窗口减小为1重新开始执行满开始算法。
    2. 个别报文段的丢失不代表网络发生了拥塞,没必要将拥塞窗口减为1降低传输效率,所以当发生个别报文段的丢失时采用快重传算法快恢复算法,当接收方收到失序的报文段时不等累计确认立刻发送确认报文段,当发送方收到三个重复的确认报文段时立刻重发该报文段,之后就不会触发该报文段的超时重传,同时发送方将慢开始门限和拥塞窗口更新为拥塞窗口的一半。

TCP 和 UDP 有哪些区别?

  • TCP 是面向连接的,UDP 是面向无连接的。
  • 在互通之前,面向连接的协议会先建立连接。例如,TCP 会三次握手,而 UDP 不会。所谓的建立连接,是为了在客户端和服务端维护连接,而建立一定的数据结构来维护双方交互的状态,用这样的数据结构来保证所谓的面向连接的特性。
  • 例如,TCP 提供可靠交付。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。我们都知道 IP 包是没有任何可靠性保证的,一旦发出去,就像西天取经,走丢了、被妖怪吃了,都只能随它去。但是 TCP 号称能做到那个连接维护的程序做的事情,这个下两节我会详细描述。而UDP 继承了 IP 包的特性,不保证不丢失,不保证按顺序到达。
  • 再如,TCP 是面向字节流的。发送的时候发的是一个流,没头没尾。IP 包可不是一个流,而是一个个的 IP 包。之所以变成了流,这也是 TCP 自己的状态维护做的事情。而UDP 继承了 IP 的特性,基于数据报的,一个一个地发,一个一个地收。
  • 还有TCP 是可以有拥塞控制的。它意识到包丢弃了或者网络的环境不好了,就会根据情况调整自己的行为,看看是不是发快了,要不要发慢点。UDP 就不会,应用让我发,我就发,管它洪水滔天。
  • 因而TCP 其实是一个有状态服务,错一点儿都不行。而 UDP 则是无状态服务,发出去就发出去了。
#Java开发##春招##实习##笔试题目##面经##笔经##Java##校招#
全部评论
好久没看过网络的东西了
2 回复 分享
发布于 2022-02-28 22:24

相关推荐

在评审的大师兄很完美:像这种一般就是部门不匹配 转移至其他部门然后挂掉 我就是这样被挂了
点赞 评论 收藏
分享
喜欢走神的孤勇者练习时长两年半:池是池,发是发,我曾池,我现黑
点赞 评论 收藏
分享
18 123 评论
分享
牛客网
牛客企业服务