【Linux C | 网络编程】详细介绍 “三次握手(建立连接)、四次挥手(终止连接)、TCP状态”

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍"三次握手(建立连接)、四次挥手(终止连接)、TCP状态" 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你------泰戈尔🍭

本文未经允许,不得转发!!!

目录


🎄一、概述

一个TCP连接通常分为3个阶:建立连接、数据传输(也称作"连接已建立")、终止连接。其中建立连接、终止连接就涉及到经常听到的三次握手,四次挥手。并且,三次握手,四次挥手 常常出现在面试中,大部分应试者一上来就是知道回复:

首先,客户端向服务端发送一个"SYN"分节;
然后,服务端向客户端发送一个"SYN+ACK"分节
最后,客户端向服务端发送一个ACK分节表示确认

这样回答是生硬的、欠缺的、不够深度的。

那请问:

1、三次握手的目的是什么?

2、为什么需要三次握手?

3、两次握手行不行?

4、SYN报文可以携带数据吗?

5、三次握手过程中,每次发送报文后,TCP处于什么状态?

6、四次挥手的过程是怎样的?

7、为什么握手是三次,挥手却要四次?

8、什么是半关闭状态?

如果上面几个问题都懂了,那不必往下看了。


🎄二、三次握手(建立连接)

TCP协议一个面向连接的协议,那么这个连接是怎么建立的呢?

TCP的连接就是通过所谓的三次握手来建立的,在网络编程中,TCP连接的建立是发生在客户端的connect函数和服务端的accept函数中的。所以,我们常常可以看到使用套接字API写TCP客户端时,都是依次调用socket、connect,而服务器常见的是依次调用socket、bind、listen、accept

✨2.1 三次握手的过程

建立一个TCP连接会进行下面步骤:

  • 1、TCP客户端调用socket函数获取到套接字句柄之后,调用connect函数发起主动打开(active open),这将导致客户端TCP发送一个SYN报文段(一个TCP头部的SYN位字段置位的TCP/IP数据包),并指明自己想要连接的端口号和它的客户端初始序列号(Initial Sequence Number, ISN)。通常,客户端还会借此发送一个或多个选项。
  • 2、TCP服务端在调用依次socket、bind、listen之后,执行被动打开(passive open),然后调用accept阻塞等待接受外来的连接。服务端接收到客户端的SYN报文后,也发送自已的SYN报文段作为响应,并包含了它的初始序列号;此外,为了确认客户端的SYN,服务端将客户端的初始序列号(Initial Sequence Number, ISN)数值加1后作为返回的ACK数值。
  • 3、客户端为了确认服务器的SYN,将服务端的初始序列号(Initial Sequence Number, ISN)数值加1后作为返回的ACK数值。

经过上面三个步骤,TCP连接就建立成功了,之后可以通过read、write等函数交互数据了。


✨2.2 为什么需要三次握手

三次握手的目的不仅在于让通信双方了解一个连接正在建立,还在于利用数据包的选项来承载特殊的信息,交换初始序列号(Initial Sequence Number, ISN)。

另外,必须是三次握手后,才可以让客户端、服务端都确认对方的发送、接收能力是否正常:

  • 第一次握手(cli -> ser):
    客户端检测服务端的接收能力。
    服务端收到客户端的SYN后,确认了客户端具有发送能力。
  • 第二次握手(ser -> cli):
    客户端收到服务端的SYN+ACK,确认了服务端具有发送能力,同时说明服务端已经收到自己的SYN(具有接收能力);
    服务端检测客户端的接收能力。
  • 第三次握手(ser -> cli):
    服务端收到客户端的ACK,说明客户端已经收到自己的SYN(具有接收能力)。

如果只有两次握手行不行呢?
只有两次握手的话,服务端消息发出去后,没受到响应,无法确认客户端是否可以接收信息。所以需要三次握手才可以建立连接。


注意:TCP的SYN段也能够承载应用数据。由于伯克利的套接字API不支持这种方式,因此它也很少为人所用


🎄三、四次挥手(终止连接)

TCP连接建立后,客户端、服务端会交互数据,最后连接的任一方可以发起终止,一般是客户端发起终止,但有些服务端处理完客户端的请求后也会发起关闭操作。

✨2.1 四次挥手的过程

  • 1、TCP连接的任一端首先调用closeshutdown函数,执行主动关闭,这会向TCP连接对端发送一个FIN报文段,并指明当前的序列号,该FIN段还包含了一个ACK段用于确认对方最近一次发来的数据。
  • 2、接收到FIN报文段的一端执行被动关闭,将发过来的序列号加1作为响应的ACK数值。上层的应用程序会接收到一个文件结束符(end-of-file)表示该连接不会再发送数据过来,read函数会返回0;
  • 3、一段时间后,接收到这个文件结束符的应用程序也会调用closeshutdown函数关闭它的套接字,这会导致它的TCP也发送一个FIN报文段
  • 4、接收到这个最后FIN报文段的一端会将接收到的序列号加1作为响应的ACK数值。

✨2.2 为什么需要四次挥手

为什么连接的时候是三次握手,终止的时候却是四次握手?

  • 三次握手:因为服务端接收到SYN报文后,可以将确认的ACK数组添加到自己的SYN报文中一并发出。
  • 四次挥手:因为TCP存在半关闭状态,就是允许连接的一端在结束它的发送后还能接收来自另一端数据。一般情况下,收到FIN报文后,并不会立刻关闭socket,而是先回复一个ACK报文,因为此时可能还有一些数据正在发送,等所有数据发送后,才会发送FIN报文,所以需要四次握手。但这并不是必然的,在《Unix网络编程卷1》有提到,第2、3步骤都出自执行被动关闭的那一端,可能被合成一个报文。

🎄四、TCP状态

TCP状态共11种:

  • 1、 客户端独有的:(1)SYN_SENT (2)FIN_WAIT1 (3)FIN_WAIT2 (4)CLOSING (5)TIME_WAIT 。

  • 2、服务端独有的:(1)LISTEN (2)SYN_RCVD (3)CLOSE_WAIT (4)LAST_ACK 。

  • 3、共有的:(1)CLOSED (2)ESTABLISHED 。

    LISTEN - 监听来自客户端的连接请求;
    SYN_SENT - 在发送连接请求后等待响应的状态;
    SYN_RCVD - 在收到和发送一个连接请求后等待对端确认的状态;
    ESTABLISHED - 代表一个已建立的连接,数据开始交互;
    FIN_WAIT1 - 主动关闭,发送完FIN,等待对端确认;
    FIN_WAIT2 - 主动关闭,发送完FIN且已收到对端确认,等待接收FIN;
    CLOSE_WAIT - 被动关闭,接收完FIN且已确认,等待发送FIN;
    CLOSING - 发送完FIN后,还没收到ACK,就收到FIN并确认,说明对端也正在关闭,等待对端确认;
    LAST_ACK - 被动关闭,发送完FIN,等待对端确认;
    TIME-WAIT - 等待2MSL,以确保对端TCP接收到连接终止的确认;
    CLOSED - 没有任何连接状态;

🎄五、总结

👉本文详细介绍了三次握手(建立连接)的过程、目的,以及四次挥手的过程、目的,最后讲解了TCP连接的11种状态。

如果真的面试遇到了三次握手、四次挥手的问题,建议这么做,

1、先把过程图画出来;

2、把三次握手、四次挥手的过程展开说一下,然后看情况,可以直接结束了,也可以再说说为什么需要三次握手、四次挥手;

3、最后,把最前面的几个问题都准备好,以防提问到。

如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

参考资料:

《Unix 网络编程卷1》

《TCP/IP 详解卷1》

《我终于搞懂了TCP的三次握手和四次挥手》https://blog.csdn.net/weixin_45393094/article/details/104965561

《面试官,不要再问我三次握手和四次挥手》https://blog.csdn.net/hyg0811/article/details/102366854

相关推荐
王磊鑫1 小时前
C语言小项目——通讯录
c语言·开发语言
幽兰的天空1 小时前
介绍 HTTP 请求如何实现跨域
网络·网络协议·http
lisenustc1 小时前
HTTP post请求工具类
网络·网络协议·http
心平气和️2 小时前
HTTP 配置与应用(不同网段)
网络·网络协议·计算机网络·http
心平气和️2 小时前
HTTP 配置与应用(局域网)
网络·计算机网络·http·智能路由器
hunter2062062 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
不会飞的小龙人2 小时前
Docker Compose创建镜像服务
linux·运维·docker·容器·镜像
不会飞的小龙人2 小时前
Docker基础安装与使用
linux·运维·docker·容器
Mbblovey2 小时前
Picsart美易照片编辑器和视频编辑器
网络·windows·软件构建·需求分析·软件需求
仟濹3 小时前
【贪心算法】洛谷P1106 - 删数问题
c语言·c++·算法·贪心算法