面试必考 | TCP 协议(第一弹)

2022-04-11 18:05:48 浏览数 (3)

敲黑板!!!

在软开岗的面试中,TCP连接的建立和终止是必考题!

相关知识点

第一弹

a. TCP三次握手以及四次挥手过程描述;

b. 为什么要有三次握手和四次挥手;

第二弹

c. TIME_WAIT状态的描述以及作用;

d. TCP是通过哪些方式提供可靠性的?

第三弹

e. 拥塞控制与流量控制机制。

由于篇幅原因,TCP相关知识点的讲解将会分为三部分来完成,第一弹将会讲较为基础的也是最常问的几点——TCP连接的建立和终止。

开始学习吧!!!

首先,我们要知道,TCP是什么:

TCP——传输控制协议。

TCP提供客户端和服务器之间的连接。TCP客户先与某个给定服务器建立一个连接,再跨该连接与那个服务器交换数据,然后终止这个连接。

TCP连接的建立

一、“三次握手”的过程

首先上图!

建立一个TCP连接的具体过程如下:

1. 服务器被动打开。通过一系列的动作(socket、bind、listen)来准备接受外来的连接。

2. 小客:歪,能听见我说话吗?

客户端通过一系列的动作(socket、connect)进行连接到服务器(要保证服务器已经被动打开了)。connect 动作会使客户 TCP 发送一个 SYN(同步)分节,它告诉服务器客户将在(待建立)连接中发送数据的初试序列号 J 。

3. 小服:歪,我能听见,你能听见我说话不?

服务器端必须对于收到的客户端的SYN 分节,要进行 ACK 确认。同时自己也得发送一个 SYN分节,它告诉客户服务器将在(待建立)连接中发送数据的初始序列号 K 。

4. 小客:妥了,我也能听见!

客户还要发送一个 ACK 对服务器发来的 SYN 进行确认!

二、为啥子必须三次握手?

用最浅显的话来说:这就像我们打电话的一个过程,在电话接通会,首先我们要确认对方能不能听到我说话:歪,能听见我说话吗?(一次握手);

然后对方告诉我他是否可以听见我说话,并且要确认我也能听见他说话:歪,我能听见,你能听见我说话不?(两次握手);

最后,我就得告诉对方:我能听见你说话!(三次握手)。

《计算机网络》中是这样说的:防止已失效的连接请求又传送到服务器端,因而产生错误。

在面试中的话,要多去解释一下:

1. 为了实现可靠数据传输。

TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤;

2. 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。

TCP连接的终止

一、“四次挥手”的过程

TCP建立一个连接需要三个分节,但是终止一个连接需要四个分节。

具体的终止流程如下:(我们假设是由客户端发起断开连接)

1. 客户端调用close,主动关闭;发送一个 FIN分节,用来关闭客户端到服务器的数据传送,表示数据发送完毕。

2. 服务器接收到FIN,它发回一个ACK,确认序号为收到的序号加1 。FIN的接收意味着在这个连接上,服务器端将再无额外数据可以接受。

3. 过一段时间后,服务器调用close关闭它的套接字,并发送一个FIN给客户端。

4. 客户端-发回 ACK 报文确认,并将确认序号设置为收到序号加1。

至此,一个TCP连接终止!

二、为什么终止连接要四次

任何一方都可以在数据传送结束后发出连接释放(终止)的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。

具体的例子我将用下面这个聊天记录来说明:

前方高能预警!!!

这里,小媛将用某对情侣 睡前的聊天记录 朴素地再演示一下为何要“四次挥手”!(被动关闭方还有数据未发完)

嘿嘿嘿

关于TCP的终止,小媛要强调一下:无论是客户还是服务器,任何一端都可以执行主动关闭。通常情况下是由客户端执行主动关闭,但是某些协议(例如HTTP/1.0)是由服务器执行主动关闭的。

Last but not least

TCP状态转换图尽管面试时候不会真的让你去画出来,但是会旁敲侧击地去问!状态转换图也是学习TCP协议的一个关键和重点,找工作的小伙伴最好可以搞明白!

CLOSED:表示初始状态。对服务端和C客户端双方都一样。

LISTEN:表示监听状态。服务端调用了listen函数,可以开始accept连接了。

SYN_SENT:表示客户端已经发送了SYN报文。当客户端调用connect函数发起连接时,首先发SYN给服务端,然后自己进入SYN_SENT状态,并等待服务端发送ACK SYN。

SYN_RCVD:表示服务端收到客户端发送SYN报文。服务端收到这个报文后,进入SYN_RCVD状态,然后发送ACK SYN给客户端。

ESTABLISHED:表示连接已经建立成功了。服务端发送完ACK SYN后进入该状态,客户端收到ACK后也进入该状态。

FIN_WAIT_1:表示主动关闭连接。无论哪方调用close函数发送FIN报文都会进入这个这个状态。

FIN_WAIT_2:表示被动关闭方同意关闭连接。主动关闭连接方收到被动关闭方返回的ACK后,会进入该状态。

TIME_WAIT:表示收到对方的FIN报文并发送了ACK报文,就等2MSL后即可回到CLOSED状态了。如果FIN_WAIT_1状态下,收到对方同时带FIN标志和ACK标志的报文时,可以直接进入TIME_WAIT状态,而无须经过FIN_WAIT_2状态。

CLOSING:表示双方同时关闭连接。如果双方几乎同时调用close函数,那么会出现双方同时发送FIN报文的情况,此时就会出现CLOSING状态,表示双方都在关闭连接。

CLOSE_WAIT:表示被动关闭方等待关闭。当收到对方调用close函数发送的FIN报文时,回应对方ACK报文,此时进入CLOSE_WAIT状态。

LAST_ACK:表示被动关闭方发送FIN报文后,等待对方的ACK报文状态,当收到ACK后进入CLOSED状态。

对文中内容有疑问或者不同意见的同学,欢迎后台留言讨论哦!

本文参考书籍主要为:《TCP/IP 详解 卷一:协议》、《UNIX网络编程卷1:套接字联网API》

有需要电子书的同学可以后台回复 “TCP” ,电子书仅作学习之用,禁止商用哦!

作者:西瓜媛

编辑:西瓜媛

本文来自程序媛驿站,未经授权不得转载.

0 人点赞