精华内容
下载资源
问答
  • 文章目录一.TCP简介二.TCP数据报结构三.TCP的三次握手四.TCP的四次挥手 一.TCP简介 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,...
  • 面试官,不要再问我三次握手和四次挥手

    万次阅读 多人点赞 2019-10-08 09:55:58
    三次握手和四次挥手是各个公司常见的考点,也具有一定的水平区分度,也被一些面试官作为热身题。很多小伙伴说这个问题刚开始回答的挺好,但是后面越回答越冒冷汗,最后就歇菜了。 见过比较典型的面试场景是这样的: ...

    温馨提示:本篇文章会长期维护及更新,详情见:https://yuanrengu.com/2020/77eef79f.html

    面试相关文章推荐:

    三次握手和四次挥手是各个公司常见的考点,也具有一定的水平区分度,也被一些面试官作为热身题。很多小伙伴说这个问题刚开始回答的挺好,但是后面越回答越冒冷汗,最后就歇菜了。

    见过比较典型的面试场景是这样的:

    面试官:请介绍下三次握手
    求职者:第一次握手就是客户端给服务器端发送一个报文,第二次就是服务器收到报文之后,会应答一个报文给客户端,第三次握手就是客户端收到报文后再给服务器发送一个报文,三次握手就成功了。
    面试官:然后呢?
    求职者:这就是三次握手的过程,很简单的。
    面试官:。。。。。。
    番外篇:一首凉凉送给你

    记住猿人谷一句话:面试时越简单的问题,一般就是隐藏着比较大的坑,一般都是需要将问题扩展的。上面求职者的回答不对吗?当然对,但距离面试官的期望可能还有点距离。

    希望大家能带着如下问题进行阅读,收获会更大。

    1. 请画出三次握手和四次挥手的示意图
    2. 为什么连接的时候是三次握手?
    3. 什么是半连接队列?
    4. ISN(Initial Sequence Number)是固定的吗?
    5. 三次握手过程中可以携带数据吗?
    6. 如果第三次握手丢失了,客户端服务端会如何处理?
    7. SYN攻击是什么?
    8. 挥手为什么需要四次?
    9. 四次挥手释放连接时,等待2MSL的意义?

    三次握手和四次挥手.png

    1. 三次握手

    三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。

    刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态。
    进行三次握手:

    • 第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN。此时客户端处于 SYN_SENT 状态。

      首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但要消耗掉一个序号。

    • 第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的 ISN + 1 作为ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_RCVD 的状态。

      在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y。

    • 第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。

      确认报文段ACK=1,确认号ack=y+1,序号seq=x+1(初始为seq=x,第二个报文段所以要+1),ACK报文段可以携带数据,不携带数据则不消耗序号。

    发送第一个SYN的一端将执行主动打开(active open),接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)。

    在socket编程中,客户端执行connect()时,将触发三次握手。

    三次握手.png

    1.1 为什么需要三次握手,两次不行吗?

    弄清这个问题,我们需要先弄明白三次握手的目的是什么,能不能只用两次握手来达到同样的目的。

    • 第一次握手:客户端发送网络包,服务端收到了。
      这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
    • 第二次握手:服务端发包,客户端收到了。
      这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
    • 第三次握手:客户端发包,服务端收到了。
      这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。

    因此,需要三次握手才能确认双方的接收与发送能力是否正常。

    试想如果是用两次握手,则会出现下面这种情况:

    如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。

    1.2 什么是半连接队列?

    服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列

    当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。

    这里在补充一点关于SYN-ACK 重传次数的问题:
    服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。
    注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s…

    1.3 ISN(Initial Sequence Number)是固定的吗?

    当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN。ISN可以看作是一个32比特的计数器,每4ms加1 。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释。

    三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。

    1.4 三次握手过程中可以携带数据吗?

    其实第三次握手的时候,是可以携带数据的。但是,第一次、第二次握手不可以携带数据

    为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。

    也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。

    1.5 SYN攻击是什么?

    服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。

    检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstat 命令来检测 SYN 攻击。

    netstat -n -p TCP | grep SYN_RECV
    

    常见的防御 SYN 攻击的方法有如下几种:

    • 缩短超时(SYN Timeout)时间
    • 增加最大半连接数
    • 过滤网关防护
    • SYN cookies技术

    2. 四次挥手

    建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。

    TCP 连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务端均可主动发起挥手动作。

    刚开始双方都处于ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:

    • 第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
      即发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
    • 第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
      即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
    • 第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
      即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
    • 第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
      即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。

    收到一个FIN只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入TIME_WAIT是正常的,服务端通常执行被动关闭,不会进入TIME_WAIT状态。

    在socket编程中,任何一方执行close()操作即可产生挥手操作。
    image.png

    2.1 挥手为什么需要四次?

    因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。

    2.2 2MSL等待状态

    TIME_WAIT状态也成为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime),它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的,因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。

    对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。

    这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。

    2.3 四次挥手释放连接时,等待2MSL的意义?

    MSL是Maximum Segment Lifetime的英文缩写,可译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

    为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。

    两个理由:

    1. 保证客户端发送的最后一个ACK报文段能够到达服务端

      这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,服务端超时重传FIN+ACK报文段,而客户端能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重新启动2MSL计时器,最后客户端和服务端都进入到CLOSED状态,若客户端在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到服务端重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则服务端无法正常进入到CLOSED状态。

    2. 防止“已失效的连接请求报文段”出现在本连接中

      客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

    2.4 为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态?

    理论上,四个报文都发送完毕,就可以直接进入CLOSE状态了,但是可能网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文

    3. 总结

    《TCP/IP详解 卷1:协议》有一张TCP状态变迁图,很具有代表性,有助于大家理解三次握手和四次挥手的状态变化。如下图所示,粗的实线箭头表示正常的客户端状态变迁,粗的虚线箭头表示正常的服务器状态变迁。

    TCP状态变迁图.jpg

    以后面试官再问你三次握手和四次挥手,直接把这一篇文章丢给他就可以了,他想问的都在这里。

    参考:《TCP/IP详解 卷1:协议》


    个人公众号:猿人谷
    公众号会有更多关于面试、源码解读、架构设计、程序人生等干货!
    期待您的关注

    在这里插入图片描述

    展开全文
  • 三次握手和四次挥手详解,觉得本博文写的很好,分享给正在学习或者学习完还对TCP的三次握手和四次挥手还不熟悉的人,相信看完之后就能明白了。
  • 简述TCP的三次握手和四次挥手过程

    万次阅读 多人点赞 2018-05-11 10:28:40
    ①TCP是一种精致的,可靠的字节流协议。 ②在TCP编程中,三路握手一般由客户端(Client)调用Connent函数发起。... 图 .TCP三次握手 (1)第一次握手:Client将标志位SYN置为1,随机产生一个值s...

     

    ①TCP是一种精致的,可靠的字节流协议。

    ②在TCP编程中,三路握手一般由客户端(Client)调用Connent函数发起。

    ③TCP3次握手后数据收发通道即打开(即建立了连接)。

    ④简述三路握手过程:

                                             图 .TCP三次握手

    (1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
    (2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
    (3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
            
    ⑤SYN攻击:

      在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了。

    使用如下命令可以让之现行:#netstat -nap | grep SYN_RECV

    ⑥TCP连接的建立:SYN分节

           终止:FIN(finish)分节

    四次挥手

    所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。

    由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
    (1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态

    (2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态
    (3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

    (4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1Server进入CLOSED状态,完成四次挥手。

    展开全文
  • TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。
  • TCP协议三次握手四次挥手形象比喻三次握手四次挥手 形象比喻 三次握手:将小明当作客户端,小红当作服务器端,两人写信告白: **第一次握手:**小明告诉小红:我喜欢你。 **第二次握手:**小红告诉小明:我知道了...

    图片来自网络,侵权请告知,会及时删除

    三次握手

    形象比喻
    将小明当作客户端,小红当作服务器端,两人写信告白:
    第一次握手:
    小明告诉小红:我喜欢你。
    第二次握手:
    小红告诉小明:我知道了,我也喜欢你。
    此时小红并不确定小明是否收到了告白信,直到
    第三次握手:
    小明回信:我也知道了,我们在一起吧。此时才真正建立连接。
    图片来自网络,侵权请告知,会及时删除

    标记位解释
    SYN请求号标记位
    ACK确认号标记位
    seq序号,代表请求方将会发送的数据的第一个字节编号
    ack返回的确认号,代表接收方收到收据后(也就是前面说的seq),代表希望对方下一次传输数据的第一个字节编号
    状态位解释
    CLOSEDclient处于关闭状态
    LISTENserver处于监听状态,等待client连接
    SYN-RCVD表示server接受到了SYN报文,当收到client的ACK报文后,它会进入到ESTABLISHED状态
    SYN-SENT表示client已发送SYN报文,等待server的第2次握手
    ESTABLISHED表示连接已经建立
    • 第一次握手:客户端第一次发送一条连接请求数据,SYN = 1,ACK = 0就是代表建立连接请求,发送的具体数据第一个字节编号记为x,赋值seq。

    • 第二次握手:服务端收到请求后,返回 客户端的SYN = 1,加上自己的确认号ACK=1,发送的具体数据第一个字节编号记为y,赋值seq,希望客户端下一次返回编号x + 1个字节为止的数据,记为ack = x + 1。

    客户端得出客户端发送接收能力正常,服务端发送接收能力也都正常,但是此时服务器并不能确认客户端的接收能力是否正常

    • 第三次握手:客户端收到服务端返回的请求确认后,再次发送数据,原封不动返回ACK = 1,这里就不需要再发送 SYN=1了,为什么呢?因为此时并不是跟服务端进行连接请求,而是连接确认,所以只需要返回ACK = 1代表确认,同样的,发送的具体数据第一个字节编号记为seq = x + 1,希望服务端下次传输的数据第一个字节编号记为ack = y + 1

    为什么TCP建立连接时候,要进行3次握手,2次不行吗?
    一句话的答案:主要目的:防止server端一直等待,浪费资源,

    如果建立连接只需要2次握手,可能会出现的情况

    假设client发出的第一个连接请求报文段,因为网络延迟,在连接释放以后的某个时间才到达server 。
    本来这是一个早已失效的连接请求,但server收到此失效的请求后,误认为是client再次发出的一个新的连接请求 。
    于是server就向client发出确认报文段,同意建立连接。
    如果不采用“3次握手”,那么只要server发出确认,新的连接就建立了 。
    由于现在client并没有真正想连接服务器的意愿,因此不会理睬server的确认,也不会向server发送数据 。
    但server却以为新的连接已经建立,并一直等待client发来数据,这样,server的很多资源就白白浪费掉了
    采用“三次握手”的办法可以防止上述现象发生 ,例如上述情况,client没有向server的确认发出确认,server由于收不到确认,就知道client并没有要求建立连接。

    四次挥手

    形象比喻
    恋爱之后,小明和小红煲电话粥。依旧将小明当作客户端,小红当作服务器端。小明跟小红说话,
    第一次挥手:
    小明说:我说完了。
    第二次挥手:
    小红说:好的,我知道了,我还没说完。
    小红继续吧啦吧啦,说完之后
    第三次挥手:
    小红告诉小明:我说完了。
    第四次挥手:
    小明收到后告诉小红:好的,我知道了。等了2MSL之后小明挂断了。
    如果此时小红说完,等了2MSL,小明一直不出声,这个时候就会重新说一次:我说完了。直到收到小明最后的回复,才挂断电话。
    图片来自网络,侵权请告知,会及时删除

    状态位: FIN = 1:代表要求释放连接

    • 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
    • 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
    • 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
    • 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手

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

    建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
    而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。为了确保正确关闭连接,所以需要四次。

    TIME_WAIT状态有什么作用,为什么主动关闭方没有直接进入CLOSED状态释放资源?

    答:防止连接关闭时四次挥手中的最后一次ACK丢失:如果主动关闭方进入CLOSED状态后,被动关闭方发送FIN包后没有得到ACK确认,超时后就会重传一个FIN包。如果客户端没有TIME_WAIT状态而直接进入CLOSED状态释放资源,下次启动新的客户端就可能使用了与之前客户端相同的地址信息,有两个危害,第一种是这个刚启动的新的客户端绑定地址成功时,就会收到了一个重传的FIN包,对新连接就会造成影响。第二种是如果该新客户端向相同的服务端发送SYN连接请求,但是此时服务端处于LAST_ACK状态,要求收到的是ACK而不是SYN,因此就会发送RST重新建立请求。

    为什么TIME_WAIT状态需要经过2MSL才能进入CLOSE状态?

    答:MSL指的是报文在网络中最大生存时间。在客户端发送对服务端的FIN确认包ACK后,这个ACK包有可能到达不了,服务器端如果接收不到ACK包就会重新发送FIN包。所以客户端发送ACK后需要留出2MSL时间(ACK到达服务器器+服务器发送FIN重传包,一来一回)等待确认服务器端缺失收到了ACK包。也就是说客户端如果等待2MSL时间也没收到服务器端重传的FIN包,则就可以确认服务器已经收到客户端发送的ACK包

    展开全文
  • TCP 三次握手和四次挥手,面试题详解,图文并茂,欢迎技术交流
  • TCP通信过程与三次握手和四次挥手

    千次阅读 2019-07-07 00:05:18
    TCP协议 TCP通信过程 三次握手 次握手

    一、理论基础

    TCP报文协议

    TCP协议报文

    1. 源端口号:数据发起者的端口号,16bit

    2. 目的端口号:数据接收者的端口号,16bit

    3. 序号:32bit的序列号,由发送方使用

    4. 确认序号:32bit的确认号,是接收数据方期望收到发送方的下一个报文段的序号,因此确认序号应当是上次已成功收到数据字节序号加1。

    5. 首部长度:首部中32bit字的数目,可表示15*32bit=60字节的首部。一般首部长度为20字节。

    6. 保留:6bit, 均为0

    7. 紧急URG:当URG=1时,表示报文段中有紧急数据,应尽快传送。

    8. 确认比特ACK:ACK = 1时代表这是一个确认的TCP包,取值0则不是确认包。

    9. 推送比特PSH:当发送端PSH=1时,接收端尽快的交付给应用进程。

    10. 复位比特(RST):当RST=1时,表明TCP连接中出现严重差错,必须释放连接,再重新建立连接。

    11. 同步比特SYN:在建立连接是用来同步序号。SYN=1, ACK=0表示一个连接请求报文段。SYN=1,ACK=1表示同意建立连接。

    12. 终止比特FIN:FIN=1时,表明此报文段的发送端的数据已经发送完毕,并要求释放传输连接。

    13. 窗口:用来控制对方发送的数据量,通知发放已确定的发送窗口上限。

    14. 检验和:该字段检验的范围包括首部和数据这两部分。由发端计算和存储,并由收端进行验证。

    15. 紧急指针:紧急指针在URG=1时才有效,它指出本报文段中的紧急数据的字节数。

    16. 选项:长度可变,最长可达40字节

    1、报文发送确认机制

    简单理解就是,接收方需要对发送方进行回复确认,这是保证可靠传输的基础。

    2、报文有序性机制

    为了保证报文的有序性,那就必须对自己的报文按顺序进行编号,这样不但可以记录自己发送到了哪个包,接收方也可以根据序号对报文进行排序串接。

    3、TCP对发送确认机制的利用

    相对于UDP的不可靠,TCP是可靠的,要做到整个过程的可靠性,那么就需要对每个传输报文都进行发送确认,包括连接建立、数据交互、连接断开中,都可以拆分成无数个最基本的发送确认过程。

    4、报文重传机制

    TCP对有序性机制的利用,因为发送确认机制的存在,可以知道对方收到了第几个包,这就顺便可以知道哪些包是否需要重传。

    5、报文初始序号生成机制

    报文的初始序号是一个跟随时间而改变随机值,原因如下:

    如果TCP在建立连接时每次都选择相同的、固定的初始序号,那么设想以下的情况:
    (1)假定主机A和B频繁地建立连接,传送一些TCP报文段后,再释放连接,然后又不断地建立新的连接、传送报文段和释放连接。
    (2)假定每一次建立连接时,主机A都选择相同的、固定的初始序号,例如,选择1。
    (3)假定主机A发送出的某些TCP报文段在网络中会滞留较长的时间,以致造成主机A超时重传这些TCP报文段。
    (4)假定有一些在网络中滞留时间较长的TCP报文段最后终于到达了主机B,但这时传送该报文段的那个连接早已释放了.而在到达主机B时的TCP连接是一条新的TCP连接。
    这样,工作在新的TCP连接下的主机B就有可能会接受在旧的连接传送的、已经没有意义的、过时的TCP报文段(因为这个TCP报文段的序号有可能正好处在现在新的连接所使用的序号范围之中)。结果产生错误。
    因此,必须使得迟到的TCP报文段的序号不处在新的连接中所使用的序号范围之中。
    这样,TCP在建立新的连接时所选择的初始序号一定要和前面的一些连接所使用过的序号不一样。因此,不同的TCP连接不能使用相同的初始序号。

    6、TCP报文初始序号互告

    因为报文的初始序号是随机的,那就必须想办法让对方知道自己的序号是多少,TCP通信是依靠在双方建立连接的过程中交互了报文初始序号。

    7、TCP报文的分类

    请求连接报文:打开了同步标志位SYN=1的报文
    回复确认报文:打开了确认标志ACK=1的报文
    终止连接报文:打开了终止标志FIN=1的报文
    数据传送报文:打开了数据推送标志位PST=1的报文

    注意SYN、FIN、PST控制具体序号seq是同一个,而ACK控制的序号是ack。因为请求连接占用的序号位置是seq,回复确认占用的序号是ack,所以在三次握手的时候,服务端可以同时打开这两个标志位开关。

    8、seq和ack序号递增规则

    发送序号seq递增规则

    只有收到了对方发来的标志位ACK=1的报文,并从收到的报文中提取ack值作为自己下次发送的seq,此时:自己seq = 对方ack;

    确认序号ack的递增规则

    • 当收到了对方发来的标志位SYN=1的报文,此时报文长度len=0,自己的ack = 对方seq + 1;
    • 当收到了对方发来的标志位PSH=1的报文,此时报文长度len=n,自己的ack = 对方seq + n;
    • 当收到了对方发来的标志位FIN=1的报文,此时报文长度len=0,自己的ack = 对方seq + 1;
    • 当收到了对方发来只打开了ACK=1的报文,自己的ack值不变,因为这个报文只是纯确认报文,需要改变的是自己的seq值;

    二、TCP通信完整过程

    TCP通信完整图解
    下面的描述是当认为所有报文都一次性成功的情况下进行,不涉及重传机制。

    三、三次握手过程

    三次连接报文
    三次握手具体过程

    • 整个过程就是互相告知自己的初始序号,并得到对方确认的过程。

    为什么不使用二次握手建立连接?

    是因为服务端回复给客户端告知自己的初始序号后,得不到客户端的确认;

    为什么不使用四次握手建立连接?

    是因为第二次握手的时候,服务端回复确认客户端的同时,顺便告知了客户端,服务端自己的初始序号,这样就可以优化成三次握手。

    1、 第1次握手,客户端发出SYN包

    发送包:打开同步标志位SYN=1,自己的报文序号是seq=x,然后进入syn_sent状态;

    2、第2次握手,服务端发出SYN和ACK包

    1)先收包:服务端收到报文后知道了客户端的报文初始序号是x。因为收到SYN=1报文,根据递增规则,自身的ack=x+1,然后开始回复客户端:打开确认标志位ACK=1,
    2) 回复包:我下次想要收到你的包的序号是ack=x+1;同时为了告知客户端知道自己的初始序号,该报文同时打开同步标志位SYN=1,服务端的初始序号seq=y,然后进入syn_rcvd状态;

    3、第3次握手,客户端发出ACK包

    1)先收包:收到服务端的报文,知道服务端的报文初始序号是y。
    因为服务端报文是【SYN=1,seq=y】报文,所以自身的ack=y+1。
    因为服务端的报文是【ACK=1,ack=x+1】,所以自身的seq=x+1。
    2)回复包:回复给服务端ACK报文并把状态变成established,服务端收到该ACK后也变成established,此时的服务端因为收到客户端发来的【ACK=1,ack=y+1】,服务端的seq=y+1;

    四、数据传输过程

    数据传输报文

    • 根据报文可以看到,PSH包的Len字段会影响到接收端的Ack【接收端的Ack=发送端的Seq+发送端的Len】;
    • 整个报文可以看出,只有其中一端在不断发送数据(暂叫发送端),另外一端只是接收数据并回复ACK(暂叫接收端),所以接收的Seq没有递增,而发送端的Ack也没有递增;

    五、四次挥手过程

    断开连接报文
    四次握手具体过程

    整个过程其实可以拆分成两个二次挥手来理解

    第1个二次握手:客户端没有数据要发送了,通知服务端要断开连接,然后服务端回复确认收到了;
    第2个二次握手:服务端也没有数据要发送了,通知客户端要关闭连接,客户端回复服务端确认收到了。

    为什么不使用二次挥手来断开连接?

    因为当客户端要求服务端关闭后,服务端仍有数据发送,那么客户端肯定就要继续接收数据,如果使用二次握手,服务端发送完数据然后回复了客户端确认收到了报文然后就直接关闭了连接,这样的情况下,并不知道客户端是否接收完数据就把流给断了。同时,客户端在等服务端回复的时间可能过长。

    为什么不使用三次挥手来断开连接?

    因为客户端通知服务端要关闭,服务端有可能还未发送完数据,如果使用三次握手来关闭,此时服务端要一直等发送完毕所有数据,才能回复客户端收到了报文可以关闭连接了,可能会导致客户端等待时间过长。

    1、第1次挥手:客户端发出FIN包

    客户端没有数据要发送了,通知服务端要关闭连接,【终结标志位FIN=1,序号seq=u】,客户端进入FIN_WAIT1状态。
    注意:此时的序号seq是根据前面客户端发了几个数据包决定的,这里当且认为是u。

    2、第2次挥手:服务端发出ACK包

    1)先收包:根据递增规则,服务端的ack=u+1
    2)回复包:打开确认标志ACK=1,自身的seq=v;服务端进入CLOSE_WAIT状态,客户端进入FIN_WAIT2状态。
    注意:此时的服务端序号seq是根据服务端在之前发了几个数据包决定的,这里当且认为当且的seq是v。

    3、第3次挥手:服务端发出FIN包

    服务端也没有数据要发送了,通知客户端要关闭连接。
    因为在第二次握手后,可能继续发了N个包给客户端,所以此时的服务端seq变成了w。
    因为在第二次握手后,没有再收到客户端的包了,可以知道此时服务端的ack仍然是ack=u+1;
    服务端进入LAST_ACK状态。

    4、第4次挥手:客户端发出ACK包

    先收包:因为服务端的【ACK=1,ack=u+1】所以此时的客户端的seq=u+1;因为服务端的【FIN=1,seq=w】所以客户端的ack=w+1;
    回复包:此时客户端方进入TIME_WAIT状态,经过2MSL时间后关闭连接;服务端收到ACK包后立即关闭。

    参考文献

    展开全文
  • 在建立TCP的过程中,会用到三次握手四次挥手,三次握手四...那么在TCP协议编程的过程中,哪一步用到了三次握手四次挥手?通过一张图来看一下: 这是一个利用TCP构建的一个C/S模型,这里只做简略介绍(Java构建C...
  • TCP三次握手和四次挥手详解(面试常见问题)

    万次阅读 多人点赞 2019-05-16 23:06:51
    大概两个月前,一位朋友在面试360集团时,在面试过程中被问及TCP三次握手和四次挥手的相关知识,他当时只知道大概,但当时面试官问他TCP三次握手过程中发送的数字是多少,他一下子就懵住了,因为这也是他第一次参加...
  • 案例测试TCP的三次握手四次挥手过程。包括C语言写的服务器端程序以及c#写的客户端程序,以及使用wirkshark进行的网络抓包分析TCP三次握手四次挥手的过程。
  • 建议首先了解三次握手四次挥手的过程再分析网络包信息:计算机网络传输层—TCP连接的建立终止(详解三次握手四次挥手) 首先开启wireshark监听网口,然后访问了google,输入简单的过滤规则进行过滤,抓包如下: ...
  • 详解TCP三次握手和四次挥手
  • 经常在前端的面试群中发现有人会碰到面试官去询问tcp的握手挥手问题,诸如你了解tcp吗,解释一下tcp的三次握手和四次挥手,我认为如果只是简单的了解这2个问题,真的那么有意义吗?所以,不防试着去多了解一点网络...
  • 简述TCP三次握手和四次挥手流程

    千次阅读 2018-07-14 15:30:32
    关于TCP的连接过程,很多从事程序开发的小伙伴应该都听过三次握手,可这三次握手的细节还是有很多人不太清楚的,特别是有些参数记不清楚,我也经常弄错,所以我根据自己的理解画了两张图,将TCP连接断开的流程简单...
  • TCP的三次握手和四次挥手详解

    万次阅读 多人点赞 2018-05-14 14:22:00
    TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接,与之相反的,采用四次挥手来断开连接: TCP标志位有6种标示,即:SYN(建立联机) 、 ACK(确认) 、 PSH(传送) 、 FIN(f结束) ...
  • 三次握手和四次挥手

    千次阅读 2019-03-02 19:45:54
    三次握手四次挥手三次握手四次挥手 学完TCP/IP的常见状态码,接下来进入TCP协议的(建立连接)三次握手四次挥手(关闭连接) 三次握手 三次握手是指建立一个TCP连接时,需要客户端服务端总共发送3个包,如...
  • TCP协议 - 三次握手和四次挥手 目录 1. 测试网站 2. 三次握手 3. 四次挥手 4. 总结 一、测试网站 ↶ 二、三次握手 ↶ 三、四次挥手 ↶ 四、总结 ↶
  • 本文主要是对客户端服务器之间的交互过程,以及TCP三次握手和四次挥手的过程做了一个简单的阐述,希望对读者有所帮助
  • 1、三次握手 1.1connect()、listen()accept()三者之间的关系 1.1三次握手的过程 1.2三次握手的状态转换安全问题 1.3三次握手的面试题总结 ...3.1TCP编程中三次握手和四次挥手的全过程 3.2TCP状态转换图
  • TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标示: SYN(synchronous建立联机)  ACK(acknowledgement 确认)  PSH(push传送)  FIN(finish结束...
  • TCP三次握手和四次挥手详解 --- 转载

    千次阅读 2020-08-09 20:20:30
    文章目录 1、三次握手 1.1connect()、listen()accept()三者之间的关系 1.1三次握手的过程 1.2三次握手的状态转换安全问题 ... 3.1TCP编程中三次握手和四次挥手的全过程 3.2TCP状态..
  • 文章目录一.TCP简介二.TCP数据报结构三.TCP的三次握手四.TCP的四次挥手 一.TCP简介 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接...
  • TCP的三次握手和四次挥手及常见面试题

    千次阅读 多人点赞 2019-10-15 09:57:04
    一、前言 今天上掘金查看热门文章,发现一篇好文★前端 100 问:能搞... 文章第16题:谈谈你对TCP三次握手和四次挥手的理解? 这是前端面试频率特别高的一个题目,接下来我们学习一下TCP的三次握手和四次挥手 二...
  • 简述TCP三次握手和四次挥手过程

    万次阅读 多人点赞 2018-03-06 09:31:00
    TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; SYN:同步序列编号(Synchronize ...
  • 一、TCP协议简介 TCP,全称Transfer Control Protocol,中文名为传输控制协议,它工作在OSI的传输层,提供面向连接的可靠传输服务。...TCP采用虚电路连接方式进行工作,在发送数据前它需要在发送方接收方建立一个...
  •  在了解三次握手和四次挥手之前,先知道TCP报文内部包含了哪些东西。 TCP报头中的源端口号目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。TCP在发送数据前必须在彼此间建立连接,这里连接意思是:...
  • 当客户端服务器通过三次握手建立了TCP连接以后,当数据传送完毕,肯定是要断开TCP连接的啊。那对于TCP的断开连接,这里就有了神秘的“四次分手”。 第一次挥手:主机1(可以使客户端,也可以是服务器端),...
  • 1. HTTP的三次握手 2. HTTP的四次挥手 3. HTTPS的三次握手

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 55,219
精华内容 22,087
关键字:

三次握手和四次挥手