zoukankan      html  css  js  c++  java
  • TCP三次握手和四次挥手详解

    TCP报文格式

     在了解三次握手和四次挥手之前,先知道TCP报文内部包含了哪些东西。

    1. TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。TCP在发送数据前必须在彼此间建立连接,这里连接意思是:双方需要内保存对方信息(例如:IP,Port…)

    2. 报文主要段的意思

        序号:表示发送的数据字节流,确保TCP传输有序,对每个字节编号

        确认序号:发送方期待接收的下一序列号,接收成功后的数据字节序列号加 1。只有ACK=1时才有效。

        ACK:确认序号的标志,ACK=1表示确认号有效,ACK=0表示报文不含确认序号信息

        SYN:连接请求序号标志,用于建立连接,SYN=1表示请求连接

        FIN:结束标志,用于释放连接,为1表示关闭本方数据流

    三次握手

    三次握手过程

    建立TCP连接时,需要客户端和服务器共发送3个包。

    • 第一次:客户端发送初始序号x和syn=1请求标志

    • 第二次:服务器发送请求标志syn,发送确认标志ACK,发送自己的序号seq=y,发送客户端的确认序号ack=x+1

    • 第三次:客户端发送ACK确认号,发送自己的序号seq=x+1,发送对方的确认号ack=y+1

     

    三次握手过程分析:

    • 第一次:客户端发送请求到服务器,服务器知道客户端发送,自己接收正常。SYN=1,seq=x
    • 第二次:服务器发给客户端,客户端知道自己发送、接收正常,服务器接收、发送正常。ACK=1,ack=x+1,SYN=1,seq=y
    • 第三次:客户端发给服务器:服务器知道客户端发送,接收正常,自己接收,发送也正常.seq=x+1,ACK=1,ack=y+1

    四次挥手

    四次挥手过程

    • 第一次挥手:客户端发出释放FIN=1,自己序列号seq=u,进入FIN-WAIT-1状态
    • 第二次挥手:服务器收到客户端的后,发出ACK=1确认标志和客户端的确认号ack=u+1,自己的序列号seq=v,进入CLOSE-WAIT状态
    • 第三次挥手:客户端收到服务器确认结果后,进入FIN-WAIT-2状态。此时服务器发送释放FIN=1信号,确认标志ACK=1,确认序号ack=u+1,自己序号seq=w,服务器进入LAST-ACK(最后确认态)
    • 第四次挥手:客户端收到回复后,发送确认ACK=1,ack=w+1,自己的seq=u+1,客户端进入TIME-WAIT(时间等待)。客户端经过2个最长报文段寿命后,客户端CLOSE;服务器收到确认后,立刻进入CLOSE状态。

    四次挥手过程分析

    • 第一次:客户端请求断开FIN,seq=u
    • 第二次:服务器确认客户端的断开请求ACK,ack=u+1,seq=v
    • 第三次:服务器请求断开FIN,seq=w,ACK,ack=u+1
    • 第四次:客户端确认服务器的断开ACK,ack=w+1,seq=u+1

    为什么要三次握手?

    举例:已失效的连接请求报文段。

    client发送了第一个连接的请求报文,但是由于网络不好,这个请求没有立即到达服务端,

    而是在某个网络节点中滞留了,直到某个时间才到达server,本来这已经是一个失效的报文,

    但是server端接收到这个请求报文后,还是会想client发出确认的报文,表示同意连接。

    假如不采用三次握手,那么只要server发出确认,新的建立就连接了,但其实这个请求是失效的请求,

    client是不会理睬server的确认信息,也不会向服务端发送确认的请求,但是server认为新的连接已经建立起来了,

    并一直等待client发来数据,这样,server的很多资源就没白白浪费掉了,采用三次握手就是为了防止这种情况的发生,

    server会因为收不到确认的报文,就知道client并没有建立连接。这就是三次握手的作用。

    为什么要四次挥手?

    为了确保数据能够完成传输。

    关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,

    所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,

    所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

    可能有人会有疑问,tcp我握手的时候为何ACK(确认)和SYN(建立连接)是一起发送。挥手的时候为什么是分开的时候发送呢?

    因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

    但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭 SOCKET,所以只能先回复一个ACK报文,

    告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步挥手。

  • 相关阅读:
    锋利的jQuery(第二版)源码下载地址
    sql(SqlServer)编程基本语法
    struts2 中请求转发与请求重定向方法
    struts2的DevMode(开发模式)模式
    ML—朴素贝叶斯
    python 全排列
    简单读懂人工智能:机器学习与深度学习是什么关系
    Postfix接收邮件后转向运行特定的脚本
    Android的View和ViewGroup分析
    简明 状态模式(5.8)
  • 原文地址:https://www.cnblogs.com/8lala/p/12511646.html
Copyright © 2011-2022 走看看