• UDP和TCP以及TCP的三次握手和四次挥手


    前言

    UDP(User Data Protocol)用户数据协议和TCP (Transition control Protocol)传输控制协议,是传输层的两种协议,TCP面向连接,UDP面向无连接。

    1. UDP和TCP的区别

    • TCP是面向连接的,连接需要一定的时间,但保证了传输的稳定性,UDP面向无连接即时性高,但不稳定,容易丢包。
    • TCP的报文要包含SYN和ACK,首部占用比较多的字节,最少需要20个,UDP的首部只需要8个字节
    • TCP的传输方式是字节流,UDP的传输方式是数据包
    • TCP只能对多连接,UDP比较随意,可以一对多,多对一或者多对多
    UDPTCP
    是否面向连接
    是否可靠
    即时性
    首部开销8个字节20~60个字节
    层传输方式数据包字节
    连接方式一对多、多对一、多对多只能一对一
    适用场景适用于实时应用如视频会议、直播、IP电话等适用于要求可靠传输的应用如文件传输

    需要注意的是不是所有的流媒体都基于UDP,如直播常用的传输协议RTMP和HLS都是基于TCP的

    2.三次握手

    2.1 三次握手的过程
    在这里插入图片描述

    1. 第一次客户端向服务发送建立连接的请求,报文首部同部位SYN=1,初始序号seq = x,发送成功后客户端状态由closed变为syn_send。
    2. 第二次握手服务端收到客户端建立连接的请求,确认后向客户端发送建立连接的请求,确认位ACK=1,确认序列号ack = x+1,同步位SYN = 1,同步序列号seq = y,发送成功后服务端的状态由listen变为syn_received。
    3. 第三次握手,客户端确认后向服务端发送确认报文ACK= 1,确认序列号ack = y+1,序号seq = x+1(因为初始值是x),此时客户端的状态变为established,服务端收到ACK报文后转态也变成established,此时双发已经建立连接。

    如果将发送建立连接请求和确认收到请求作为一次连接的话,三次握手可以看做两次连接确认和一次syn的确认:

    • 客户端向服务端建立连接服务端同意
    • 服务端向客户端建立连接客户端同意
    • 客户端确认是最新的syn后同意建立连接

    2.2 为什么是三次握手?

    第一次握手确认了客户端的发送能力和服务端的接收能力,第二此握手确认了客户端和服务端的发送和接收能力。第三握手确认syn是最新的,是为了防止网络延迟,导致服务端一直处于等待状态,造成资源的浪费。具体过程是这样的:

    假如客户端发送SYN的时候网络节点中出现延迟,客户端等不到服务端的ACK,会再次发送SYN,服务端收到SYN并且成功跟客户端建立连接,之后服务端接收到了被延迟的SYN,向客户端发送ACK确认进行第二次握手,客户端经过判断发现这个SYN是重新上传过的并且已经成功建立连接了,就不会再向服务端发送ACK,服务端收不到客户端的确认ACK就一直处于等待状态。

    3. 四次挥手

    在这里插入图片描述

    1. 第一次挥手:客户端向服务端发送FIN
    2. 服务端向客户端发送确认的ACK
    3. 服务端向客户端发送FIN申请关闭连接
    4. 客户端向服务端发送ACK,服务端收到ACK变为closed状态,客户端等待2MSL后变为closed状态,此时挥手完成

    四次挥手整体可以看做是两关闭连接(FIN)请求和请求确认(ACK)的过程。

    3.2 为什么是四次挥手?不能是三次握手吗?服务端的FIN不能跟ACK一起发送吗?

    四次挥手是因为每次FIN都都要经过ACK的确认,服务端在收到FIN不能立即关闭是因为服务端可能还有没发送完的数据,服务器在等数据发送完成后才会主动发送FIN申请关闭连接。

    3.3 为什么客户端要等待2MSL后才关闭?

    • 确保服务端收到ACK
    • 确保2MSL内没有新的报文到客户端

    确保服务端成功收到ACK后变成关闭状态。2MSL是两个报文的最大生存时间,够数据传输的一个来回。在2MSL时间内如果客户端没有再接收到服务端的数据,说明服务端已经成功关,这时客户端才变为关闭状态,四次挥手完成。

    3.4 TCP是否每次都需要三次握手?
    使用fast-open只需要两次握手

    1. 客户端发送syn的时候在fast-open上携带上cookie
    2. 服务端产生cookie在ACK中返回给客户端
    3. 客户端存储cookie
      之后客户端发送syn都会携带式cookie,服务端验证cookie有效后会在ACK中直接将数据返回,只需要两次握手,如果验证cookie无效再进行三次握手。

    3.5 常见的TCP攻击方式

    • 半连接和全连接
    • 客户端发送SYN请求,服务端收到后向客户端发送ACK和SYN,状态从LISTEN变为SYN_RCVD,此时这个连接就被推入了SYN队列也就是半连接队列,当客户端收到SYN返回ACK后三次握手完成,这个连接会被推入TCP队列,也就是全连接。

    SYN flood攻击
    当客户端短时间内发送大量的SYN的时候,服务端返回大量的ACK,半连接池吃紧,服务端收不到客户端的ACK,超时重发

    如何解决?

    1. 加大半连接池
    2. SYN cookie: 服务端在接收到SYN后不立即分配资源,根据SYN计算出cookie携带在在返回的ACK上,客户端客户端在ACK里面加上cookie,服务端校验cooike正确分配资源。

    传送门:OSI七层模型和TCP/IP协议

  • 相关阅读:
    Python 依赖管理及打包三方库 Poetry
    MyBatis注解开发
    std::decay 源码分析
    会议OA项目-其它页面->自定义组件应用,其它界面的布局
    Pandas的DataFrame & Series【详解】
    SpringCloud Alibaba微服务第3章Nacos究竟是什么
    常见的4种Bug 出现原因和解决方案
    动态规划简述;斐波那契数列自顶向下和自底向上
    java面试强基(17)
    el-dialog关闭后表单数据缓存没清空【已解决】
  • 原文地址:https://blog.csdn.net/qq_44621394/article/details/127096332