乐趣区

关于java:关于-TCP-连接的一些面试题

一、为什么是三次握手?而不是两次呢?

有三个起因:

1)第一个起因也是次要起因:避免旧的反复连贯建设造成凌乱。网络拥挤的状况下,客户端可能发送屡次连贯申请,而旧的连贯申请可能先达到服务端,这时如果是两次握手,服务端返回 ACK 报文就建设了连贯,等到新的连贯申请达到后,此时旧连贯曾经建设,所以会造成凌乱;三次握手就能够防止这种状况,当服务端返回 ACK 报文时,客户端发现 ACKnum 与预期不符,就会发送 RST(Reset) 报文给服务端示意重置连贯,服务端回退到 LISTEN 状态;

接管方收到 RST 报文时将采取以下三种措施:

  1. 接管方处于 非同步状态SYN_SENT, SYN-RECEIVED),则返回到 LISTEN 状态;
  2. 接管方处于 同步状态ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT),则终止连贯,回到 CLOSED 状态;

2)为了保障单方都具备接管和发送能力:如果只有两次握手,那么服务端不晓得本人的发送能力和客户端的接管能力是否失常;如果三次握手,客户端返回确认音讯,服务端收到音讯,就能够确认本人的发送能力和客户端的承受能力失常;

3)避免曾经生效的连贯申请达到服务端导致建设连贯浪费资源:当客户端发送的 SYN 报文被阻塞,客户端又重发了 SYN 报文,胜利与服务端建设连贯,而后传输完数据后敞开了连贯,尔后生效的 SYN 报文达到服务端,如果是两次握手,会再次建设一个连贯,服务端会始终期待客户端发送数据从而节约了资源。

二、为什么建设连贯握手三次,敞开连贯时须要是四次呢?

因为建设连贯的时候服务端发送的报文中同时设置了 SYN 和 ACK 两个管制位,所以缩小了一次报文的发送;而敞开连贯时,被动敞开方发送管制位 FIN 置 1 的报文,示意数据曾经发送结束,能够敞开连贯,但此时接管方可能还在发送数据,不能立即敞开数据传输通道,所以不能把 FIN 包和 ACK 包同时发送,接管方先发送 ACK 包确认,而后期待利用过程发来告诉说数据发送结束了,再发送 FIN 包。

三、为什么 TIME_WAIT 状态须要通过 2MSL 能力返回到 CLOSED 状态?

MSL(maximum segment lifetime):TCP 定义 MSL 为 120s,同时容许批改这个值;

两个起因:

1)保障客户端发送的最初一个 ACK 包能达到服务端,当这个包失落时,服务端会再次发送 FIN 包,所以 2MSL=ACK 包达到服务端 + 服务端重发 FIN 包,接着客户端发送 ACK 包,并重启 2MSL 计时器;

2)保障敞开连贯前,本次连贯中产生的所有数据报文都从网络中隐没,避免与新的连贯混同。

四、为什么 FIN 和 SYN 要额定耗费一个序号?

因为 FIN 包和 SYN 包都须要确认,如果不占用序号的话,就无奈分别 ACK 包确认的是哪一个报文。

五、单方同时发送申请建设 TCP 连贯,会产生什么?

      TCP A                                            TCP B

  1.  CLOSED                                           CLOSED

  2.  SYN-SENT     --> <SEQ=100><CTL=SYN>              ...

  3.  SYN-RECEIVED <-- <SEQ=300><CTL=SYN>              <-- SYN-SENT

  4.               ... <SEQ=100><CTL=SYN>              --> SYN-RECEIVED

  5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...

  6.  ESTABLISHED  <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED

  7.               ... <SEQ=101><ACK=301><CTL=ACK>     --> ESTABLISHED

                Simultaneous Connection Synchronization

首先解释一下图中符号的含意:

  • 右箭头 (–>):从 A 发送到 B 的 TCP 报文段,或者 B 接管到了 A 的报文;
  • 左箭头 (<–):从 B 发送到 A 的 TCP 报文段,或者 A 接管到了 B 的报文;
  • 省略号 (…):TCP 报文段仍滞留在网络中(delayed);
  • 失落 (XXX):TCP 报文段失落或者被回绝;
  • 正文会放在括号中;
  • TCP 状态代表了处于两头的报文段收回或者达到之后的状态(AFTER);

先说论断:单方同时发送申请建设 TCP 连贯,最终只会建设一个 TCP 连贯

接着咱们逐行来剖析这个连贯过程产生了什么:

  1. 单方都处于 CLOSED 状态;
  2. 此时 A 发送 SYN 报文申请建设 TCP 连贯;
  3. A 发送的连贯报文还未达到 B 时,B 也发送一个报文申请建设连贯,A 收到后就进入SYN-RECEIVED 状态;
  4. A 发送的连贯报文达到 B,B 也进入 SYN-RECEIVED 状态;
  5. A 发送 SYN+ACK 报文,示意申请建设连贯同时确认应答 B 发送的 SYN 报文,留神,这里的序列号 SEQ 是初始序列号,所以与第 1 次发送的序列号统一;
  6. B 也同时发送 SYN+ACK 报文,A 收到后就进入 ESTABLISHED 状态,示意胜利建设连贯;
  7. 最初 A 发送的 SYN+ACK 报文达到 B 端,咱们留神到,第 7 行 B 收到的报文与第 5 行 A 发送的报文不一样,这是为什么呢?这是因为后面 B 曾经收到 A 发送的 SEQ=100 的报文了(见第 4 行),所以实际上 B 只接管 A 发送的从序列号 101 开始的 ACK 报文,这就是第 7 行和第 5 行的报文不一样的起因。B 收到报文后也进入 ESTABLISHED 状态,最终只建设了一个 TCP 连贯。
 5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...
 
 7.               ... <SEQ=101><ACK=301><CTL=ACK>     --> ESTABLISHED

六、在建设 TCP 连贯时,一个旧的 SYN 报文达到服务端,会产生什么?

      TCP A                                                TCP B

  1.  CLOSED                                               LISTEN

  2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               ...

  3.  (duplicate) ... <SEQ=90><CTL=SYN>               --> SYN-RECEIVED

  4.  SYN-SENT    <-- <SEQ=300><ACK=91><CTL=SYN,ACK>  <-- SYN-RECEIVED

  5.  SYN-SENT    --> <SEQ=91><CTL=RST>               --> LISTEN


  6.              ... <SEQ=100><CTL=SYN>               --> SYN-RECEIVED

  7.  SYN-SENT    <-- <SEQ=400><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED

  8.  ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK>      --> ESTABLISHED

                    Recovery from Old Duplicate SYN

当服务端 B 处于 SYN-RECEIVED 状态时,来自客户端 A 的一个旧 SYN 报文达到:

  1. 服务端无奈判断这个报文是否是旧的,所以失常返回应答报文;
  2. 客户端收到 ACK 报文后发现 ACKnum(应答号)不正确,所以返回一个 RST 报文示意重置;
  3. 服务器收到 RST 报文后,回到 LISTEN 监听状态;

七、在一个失常通信的 TCP 连贯中,某一端解体了,另一端持续发送数据,会产生什么?

解体方的操作系统内核会发送一个 RST 重置报文到发送方,发送方收到 RST 报文后会终止连贯。

八、第三次握手失败了,会产生什么?

咱们先看下根本的三次握手过程:

     TCP A                                                TCP B

  1.  CLOSED                                               LISTEN

  2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               --> SYN-RECEIVED

  3.  ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED

  4.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK>       --> ESTABLISHED

  5.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED

          Basic 3-Way Handshake for Connection Synchronization

在上述过程中的第 4 行,A 发送的应答报文失落了,此时 B 处于 SYN-RECEIVED 状态,会产生什么?

  1. 当计时器超时了而 B 还没收到 A 的应答报文,B 就认为它之前发送的 SYN+ACK 报文已失落,会触发超时重传,重传次数默认 5 次;
  2. 如果重传指定次数后还没收到应答,则 B 就会敞开连贯;
  3. 此时 B 可能处于 SYN-RECEIVED 状态或者 CLOSED 状态:

    • CLOSED 状态:B 发送重置报文给 A,A 收到后就敞开连贯;
    • SYN-RECEIVED 状态:如果 B 之后收到失常的应答报文(第 4 行),那么连贯胜利建设;如果收到传输数据的申请(第 5 行),那么连贯也能胜利建设,因为传输数据的报文蕴含了应答号;

参考资料

  1. RFC-793
  2. 小林 coding
  3. 全网最具深度的三次握手、四次挥手解说
退出移动版