关于tcp:拜托面试不要再我TCP三次握手与四次挥手了

9次阅读

共计 4074 个字符,预计需要花费 11 分钟才能阅读完成。

摘要

在互联网大厂面试过程中对于计算机中网络常问的一个问题就是对于传输层外面的协定:TCP 协定,TCP 协定规定了网络通信中点对点的通信, 基于 PORT 寻址到对应的主机上的某一个应用程序(一个网络数据包过去之后, 因为各个应用程序是共用一块网卡接管网络数据包数据, 所以为了确认此网络数据包到底是发给我本机的哪个应用程序的呢?QQ、微信、钉钉等, 因此引出了 TCP 协定基于 port 的点对点通信,TCP 协定定一个一套标准, 理论电脑网络通信的过程中应用的是底层实现了 tcp 协定的编程标准的 socket 来进行点对点通信),TCP 协定进行通信的关键步骤: 点对点建设连贯(TCP 三次握手)、散失拆分数据传输、点对点开释连贯(TCP 四次挥手)。

面试题剖析

1、画一下 TCP 三次握手的流程图?为啥是三次而不是二次或者四次呢?而后连环炮诘问, 说一下 TCP 四次握手的过程?

背景

咱们罕用的应用 tcp 协定编程次要是:socket 编程, 比方 netty、java nio、socket 等;基于 ip 地址加端口号进行点对点通信时候其实是十分根底的。会经验一个 tcp 的 3 次握手过程建设连贯、而后传输数据,最初通过四次挥手开释连贯。

内容

三次握手次要是传递报头数据:ACK,SYN,ack,seq;

1_TCP 三次握手 / 四次离别传递报头数据阐明


TCP 数据包由包头跟数据组成; 包头次要由发送方端口跟接管方端口组成, 以及每次我发送的数据包的起始字节数据序号 seq, 以及对每次发送者的确认号 ack;

TCP 的 3 次握手是在进行数据传输发送前的筹备工作, 所以只须要替换一些头部信息(说明性形容信息), 所以咱们先弄清楚下信息替换的描述性信息:

序列号: TCP 数据包的 第一个字节数据 编号 (TCP 把连贯中发送的所有数据字节都编上一个序号, 占 4 个字节,32 位, 用来标记数据段的程序)。
确认号 ack: 期待收到对方 下一个报文段的第一个数据字节的序号 ()。
确认 ACK: 用来限定阐明确认号 ack. 仅当 ACK= 1 时,确认号字段才无效。ACK= 0 时,确认号有效 (占 1 位)。
同步 SYN: 建设连贯时候的同步序列, 当 SYN=1,ACK= 0 时示意:这是一个连贯申请报文段 (若批准连贯,则在响应报文段中使得 SYN=1,ACK=1。因而,SYN= 1 示意这是一个连贯申请,或连贯承受报文。SYN 这个标记位只有在 TCP 建产连贯时才会被置 1,握手实现后 SYN 标记位被置 0)。
终止 FIN:用来开释一个连贯。FIN= 1 示意:此报文段的发送方的数据曾经发送结束,并要求开释运输连贯。

:ACK、SYN 和 FIN 这些大写的单词示意标记位,其值要么是 1,要么是 0;ack、seq 小写的单词示意序号。

2_TCP 三次握手图解.


理清画出 tcp 三次握手的外围思路:替换数据 + 进入的状态
第一次握手:客户端被动发动连贯申请, 发送:SYN=1,ACK=0,seq=x, 此时客户端进入 SYN-SENT(同步发送)状态。
第二次握手:服务端接管到客户端发动连贯申请, 而后回复批准建设连贯:SYN=1,ACK=1,ack=x+1,seq=y, 此时服务端进入:SYN-RCVD(同步接管状态)。
第三次握手:客户端收到服务端对立建设连贯的申请, 而后发送准备就绪:ACK=1,ack=y+1,seq=x+1(因为曾经建设了连贯, 所以不再发送 SYN, 而 ACK= 1 是确保 ack 无效的), 此时客户端进入 ESTA-BLISHED 状态, 服务端收到数据之后也会进入 ESTA-BLISHED 状态。而后进入数据传输。

3_TCP 四次握手图解


第一次挥手: 客户端在 ESTA-BLISHED 已连贯的状态下发动开释连贯申请:FIN=1,seq=u, 此时客户端进入 FIN-WAIT1(终止期待状态 1), 此时客户端不再发送数据。

第二次挥手: 服务端在承受到连贯开释申请后, 发送确认音讯:ACK=1,ack=u+1,seq=v; 此时服务端进入敞开期待状态, 此时服务端会告诉应用程序做连贯敞开的筹备工作. 客户端收到确认音讯之后进入 FIN-WAIT2(终止期待 2 状态)。

第三次挥手: 服务端做完连贯敞开筹备工作之后, 告诉服务端发送连贯敞开申请给客户端:FIN=1,seq=w; 此时服务端进入 LAST-ACK 状态。

第四次挥手: 客户端承受到服务端的连贯开释音讯之后发送确认音讯:ACK=1,ack=w+1,seq=u+1, 此时客户端进入工夫期待状态, 在 2MSL 时间段内,敞开连贯进入连贯 TIME_WAIT 工夫期待状态。服务端收到音讯之后进入 CLOSED。

4_常见面试题扩大

1、传输层数据发送都须要建设连贯吗? 说说 TCP 跟 UDP 协定的区别?

为什么须要握手这个操作, 能不能不握手?在网络上发送数据包事能够不必握手的, 应用握手的原理仅仅是为了满足 在不牢靠信道上牢靠地传输信息; 对于主机电脑网卡而言, 不同主机间发送数据包, 先发的数据 A 并不一定比后发的数据 B 先到。只是 TCP 协定会做非凡解决而已。

如果读者比照一下 UDP 的通信流程和 TCP 的通信流程, 能够发现: 在 UDP 协定中, 是没有握手这个操作的。

这里就引出了 TCP 与 UDP 的一个根本区别,TCP 是牢靠通信协议, 而 UDP 是不牢靠通信协议。
TCP 的可靠性含意: 接管方收到的数据是残缺, 有序, 无差错的。
UDP 不可靠性含意: 接管方接管到的数据可能存在局部失落, 程序也不肯定能保障。
UDP 和 TCP 协定都是基于同样的互联网基础设施, 且都基于 IP 协定实现, 互联网基础设施中对于数据包的发送过程是会产生丢包景象的, 为什么 TCP 就能够实现牢靠传输而 UDP 不行?

TCP 协定为了实现牢靠传输, 通信单方须要判断本人曾经发送的数据包是否都被接管方收到, 如果没收到, 就须要重发。为了实现这个需要, 很天然地就会引出序号(sequence number)和 确认号(acknowledgement number)的应用。

发送方在发送数据包(假如大小为 10byte)时,同时送上一个序号(假如为 100),那么接管方收到这个数据包当前,就能够回复一个确认号(110 = 100 + 10)通知发送方“我曾经收到了你的数据包,你能够发送下一个数据包序号从 110 开始”。

2、TCP 连贯握手为啥是三次而不是二次或者四次呢?

原理:在不牢靠信道上牢靠地传输信息 .
可靠消息传输是基于咱们的 ack: 确认号实现的,如果咱们采纳 2 次握手,client 端发送建设连贯申请后,server 端收到音讯之后, 发送确认收到音讯之后就分配资源期待 client 端发送数据,会存在在不牢靠的网络通道下,client 端发送了数据包 A 而后又发送了数据包 B, 因为网络起因, 后发送的数据包 B 先达到, 而后 server 端收到数据包之后给其分配资源, 筹备接收数据, 此时 client 跟 server 端就失常发送数据。然而因为前面达到的数据包 A 又达到建设连贯, 此时 server 端就会再次分配资源。然而此时 client 端曾经能够失常发送数据, 曾经进入了连贯建设状态所以不再理睬 server 端的资源分配,这样的话, 在信道不牢靠的状况下, 多个申请发送时候会创立大量连贯申请, 服务端资源节约。因为 3 次握手曾经能够建设连贯了不须要 4 次。

延长: 三次握手不是 TCP 自身的要求, 而是为了满足 ” 在不牢靠信道上牢靠地传输信息 ” 这一需要所导致的. 请留神这里的实质需要, 信道不牢靠, 数据传输要牢靠. 三次达到了, 那前面你想接着握手也好, 发数据也好, 跟进行牢靠信息传输的需要就没关系了. 因而, 如果信道是牢靠的, 即无论什么时候收回音讯, 对方肯定能收到, 或者你不关怀是否要保障对方收到你的音讯, 那就能像 UDP 那样间接发送音讯就能够了。

3、为什么 TCP 连贯断开是 4 次离别, 而不是 3 次或者 5 次?

TCP 的 4 次挥手为了保障资源的精确开释, 前两次离别是确保 client 端发送的开释申请被服务端接管到, 后两次离别是为了 server 确保本人资源开释申请 client 端曾经收到。然而敞开连贯时,当 Server 端收到 FIN 报文时,很可能并不会立刻敞开 SOCKET,所以只能先回复一个 ACK 报文,通知 Client 端,” 你发的 FIN 报文我收到了 ”。只有等到我 Server 端所有的报文都发送完了,我能力发送 FIN 报文,因而不能一起发送。故须要四步握手。

为什么不是 3 次: 因为服务端资源开释是有一个绝对的过程, 如果 3 次离别就敞开关联的话, 应用程序可能还没有收到连贯敞开申请。

4、为什么 TIME_WAIT 状态须要通过 2MSL(最大报文段生存工夫)能力返回到 CLOSE 状态?

尽管按情理,四个报文都发送结束,咱们能够间接进入 CLOSE 状态了,然而咱们必须假象网络是不牢靠的,有能够最初一个 ACK 失落。所以 TIME_WAIT 状态就是用来重发可能失落的 ACK 报文。在 Client 发送出最初的 ACK 回复,但该 ACK 可能失落。Server 如果没有收到 ACK,将一直反复发送 FIN 片段。所以 Client 不能立刻敞开,它必须确认 Server 接管到了该 ACK。Client 会在发送出 ACK 之后进入到 TIME_WAIT 状态。Client 会设置一个计时器,期待 2MSL 的工夫。如果在该工夫内再次收到 FIN,那么 Client 会重发 ACK 并再次期待 2MSL。所谓的 2MSL 是两倍的 MSL(Maximum Segment Lifetime)。MSL 指一个片段在网络中最大的存活工夫,2MSL 就是一个发送和一个回复所需的最大工夫。如果直到 2MSL,Client 都没有再次收到 FIN,那么 Client 推断 ACK 曾经被胜利接管,则完结 TCP 连贯。

5、如果曾经建设了连贯,然而客户端忽然呈现故障了怎么办?

TCP 设有一个保活计时器, 客户端如果呈现故障, 服务器不能始终等上来白白浪费资源。服务器每收到一次客户端的申请后都会从新复位这个计时器,工夫通常是设置为 2 小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,当前每隔 75 秒钟发送一次。若一连发送 10 个探测报文依然没反馈,服务器就认为客户端出了故障,接着就敞开连贯。

参考

https://blog.csdn.net/lengxia…

正文完
 0