• TCP三次握手建立连接和四次挥手释放连接


    TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种端点叫作套接字(socket),由IP地址 + 端口号组成。例如,若IP地址为192.3.4.16 而端口号为80,那么得到的套接字为192.3.4.16:80。

    一、三次握手建立连接

    1、什么是三次握手?
    三次握手,就是客户端与服务器建立连接之前,先进行三次简单的通信,成功之后才正式建立连接。其目的是为了确认信道是否安全,双方是否具有收发消息的能力。

    客户端:老铁,能听到我说话吗?
    
    服务器:能听到。你能听到我说话吗?
    
    客户端:也能听到。好了,那我开始说正事了。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如图所示
    在这里插入图片描述
    2、铺垫知识

    序号(sequence number):seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。

    确认号(acknowledgement number):ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。

    标志位(Flags):共6个,即URG、ACK、PSH、RST、SYN、FIN等。具体含义如下:

    URG:紧急指针(urgent pointer)有效。
    ACK:确认序号有效。(为了与确认号ack区分开,我们用大写表示)
    PSH:接收方应该尽快将这个报文交给应用层。
    RST:重置连接。
    SYN:发起一个新连接。
    FIN:释放一个连接。

    seq序号、ack序号:用于确认数据是否准确,是否正常通信;
    标志位:用于确认/更改连接状态。

    3、三次握手的详细过程

    最开始的时候客户端和服务器都是处于CLOSED状态。主动打开连接的为客户端,被动打开连接的是服务器。

    1)TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器进入LISTEN(监听)状态;

    2)TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文。
    报文首部中的同步位SYN=1,同时选择一个初始序列号 seq=x ;此时TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。

    3)TCP服务器收到请求报文后,如果同意连接,则发出确认报文。
    确认报文中ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y;此时TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。

    4)TCP客户进程收到确认后,还要向服务器给出确认。
    确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1;此时TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。

    5)当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。
    在这里插入图片描述

    在这里插入图片描述
    SYN:用于建立连接。

    ACK:用于确定收到了请求。

    seq:发送自己的数据。

    ack:发送接收到的对方的数据。

    3、为什么是三次握手,而不是2次、4次?
    确认对方具有收发能力需要一来(询问)、一回(应答),共2次通信;那么客户端和服务器各自向对方确认,应该是4次握手。但为了节省,服务器端将应答和询问合在一次通信中完成,所以变成了3次。

    客户端:老铁,能听到我说话吗?(询问)
    
    服务器:能听到。你能听到我说话吗?(应答、询问)
    
    客户端:也能听到。好了,那我开始说正事了。(应答)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    也有一些比较复杂的解释:

    一句话,主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。

    如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

    如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

    4、三次握手过程中,如果丢包咋办?
    不同步骤丢包,处理有些差别。基本都是丢包的话,会重传、重试,超过阈值后放弃。

    因为有重试重传的机制,容易被别有用心地进行攻击。如SYN攻击:

    攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送SYN包,服务器回复确认包,并等待客户的确认。由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,导致目标系统运行缓慢,严重者会引起网络堵塞甚至系统瘫痪。

    SYN 攻击是一种典型的 DoS/DDoS 攻击。

    三、四次挥手释放连接

    1、详细过程
    在这里插入图片描述
    数据传输完毕后,双方都可释放连接。最开始的时候,客户端和服务器都是处于ESTABLISHED状态,然后客户端主动关闭,服务器被动关闭。

    2、为什么建立连接是三次握手,关闭连接确是四次挥手呢?

    建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里,合并发送给客户端。

    而关闭连接时,服务器收到对方的FIN报文,仅仅表明对方不再发送数据了,但是还能接收数据;而自己也未必全部数据发送完毕,所以服务器可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文表示同意现在关闭连接。因此,在关闭连接时,ACK和FIN一般都会分开发送,从而导致多了一次。

    参考文章:
    两张动图-彻底明白TCP的三次握手与四次挥手
    TCP的三次握手各字段(ack,seq,ACK,SYN)是什么意思?

  • 相关阅读:
    小说阅读软件阅读界面设计
    【NSMutableDictionary Objective-C语言】
    Bellman-Ford算法
    申报消防设施设计乙级资质关于财务审计报告的要求
    MySQL操作库
    Html 后端了解基础
    Java操作文件的方法大全
    谈谈mysql中的各个关键字
    1-十四烷基-3-甲基咪唑六氟磷酸盐([C14MIm][PF6])修饰纳米SiO2二氧化硅(mg级瓶装)
    springboot 多线程实现
  • 原文地址:https://blog.csdn.net/leftfist/article/details/126910721