| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> TCP三次握手与四次挥手 -> 正文阅读 |
|
[网络协议]TCP三次握手与四次挥手 |
1. 三次握手(建立连接) (1) 客户端发送一个 SYN 段(SYN 标志位置位),包含初始序号 ISN,在图 中,这个序号的值 seq = 2379453243. 在这个过程中,客户端是通过 connect 函数发起连接请求的,此时 connect 函数阻塞,等待服务器发回 ACK 应答。 (2) 服务器端接收到 SYN 段后(listen),知道有新的连接请求到来,于是初始化一个序号 ISN,在上面的例子中这个值是 seq = 4269857. 此时服务器创建一个 TCP 段,将 SYN 和 ACK 标志置位,让 seq = 4269857, ack = 2379453244,然后将这个 TCP 段发送给客户端。这个步骤完全有内核完成,并将此连接加入未完成连接队列。 (3) 客户端再次收到服务器发送来的 TCP 段后,检查到带有 SYN 和 ACK 标志,于是客户端一方连接已经建立成功,此时 connect 函数返回。客户端创建一个 TCP 段,将 ACK 标志置位,同时将 ack 的值设置为 4269858,发送给服务器。 (4) 服务器收到客户端的 ACK 后,将此连接移到已完成连接队列(accept)。 三次握手是有效的 先解释建立连接的一个基础条件:假设 A 和 B 要建立连接,A 给 B 发送 SYN,直到 A 确定下来 B 已经收到,可以用 ACK + 超时重传机制来实现。 同样的,B 也可以利用 ACK + 超时重传机制给 A 发送 SYN 段。 这样双方都可以保证对方收到了自己的 SYN 段。写成步骤就是下面这样: (1) A ------ SYN ------> B (2) B ------ ACK ------> A (3) B ------ SYN ------> A (4) A ------ ACK ------> B 聪明的同学一眼就可以看出来步骤 2 和 3 可以合并成一个。因此,三次握手是有效的,正确的。 为什么要三次握手? 为什么要三次握手,而不是两次,即为什么客户端需要第三次握手发送ACK?? 理论上,A发送SYN后,B发送ACK,A收到ACK就代表双向连接是通的。可为什么A在收到ACK后需要回一次ACK给B? 从两方面解释: (1) 防止某个在网络中滞留的 SYN 段突然又被传送到服务器端 在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。 假设某上在网络中滞留的 SYN 突然被传送到服务器端,服务器收到此 SYN,必然认为是有客户发起了请求,于是回复 SYN + ACK. 这对应于前面讲的步骤 2 和 3,接下来服务器就需要等待对端回复的 ACK,对应于步骤 4. 实际上,根本就不存在这样的一个客户端,因为 SYN 段只是一个滞留数据段,客户端早已不存在,因此服务器永远等不到对端的 ACK 回复,经过一次次数的超时重传,服务器最终会放弃这个连接。 显然,这种滞留的 SYN 会极大的浪费服务器资源。SYN 泛洪攻击服务器就是利用的这个原理。 (2)?确认双方的初始序号 —— ISN 有些同学会有疑问,即使没有三次握手,就不能利用 ACK + 超时重传发送数据了吗,也就是说使用 UDP 协议 + ACK 能不能完成 TCP 的功能? 不妨这样看,你按顺序发了两个 UDP 数据报,假设为数据报 1 和 2,而对端先收到数据报 2,其次才收到数据报 1. 这时候,对端凭什么才能知道哪个数据报应该在前,哪个在后呢?在你不解释的情况下,对端就认为数据报 2 排在前面,数据报 1 排在后面。 为了解决这个问题,你不得不在你的 UDP 报文里加入编号,对端收到了这个报文,就可以自己根据报文编号排序了。好了,这个问题也解决了,还有一个问题,如何才能告诉对方,哪个 udp 报文是第一个报文? 假设你连续发送了 1 、2、3、4、5 号报文,对方收到了3、4、5,还有 1 和 2 对方暂时还没收到,你说,对端能不能把 3、4、5 交付给应用程序,虽然 3、4、5 的顺序没错?显然不行,你还得告诉对方哪个报文是第一个报文,是不是?然后你又加了一个标记在报文 1 里,当对方收到报文 1 了,就知道 1 号报文是第一个报文了,于是就按照顺序从 1 号报文开始,把数据交付给上层应用程序了。 上面的过程,也就是确定初始报文序号的过程,可以单独提炼出来。为了这样就简化了程序的设计,不妨把确定初始报文序号的过程在一开始就确定下来,只要没确定下来,就不发数据。对应到三次握手,本质上就是确定 ISN,即初始序号。 因此,三次握手的目的之一,即建立 TCP 连接的目的,是为了确认双方的初始序号 —— ISN. 再来一些补充,有同学还会问,双方约定起始报文序号就是 1 不就好了?没错,确实可以,但是这样不安全,黑客非常容易构造出一个合法序号的 tcp 报文对你进行攻击。因此 ISN 在一般会选取一个随机数,这取决于你的协议栈具体实现。 2. 四次挥手(断开连接) 客户端主动关闭连接 —— TCP 四次挥手
(1) 首先,由客户端调用 close,将这一端称为主动关闭(active close)。然后该端发送一个 FIN 段到对端。 (2) 接收到 FIN 段的服务器执行被动关闭(passive close)。接下来,接收到此 FIN 段的服务器回复 ACK 进行确认(实际上是由内核自动完成回复的),同时内核会传递一个文件结束符 EOF(放在缓冲区末尾) 给应用进程,应用进程read会读取到EOF表示发送端连接已关闭。 (3) 一段时间后……服务器端也没有数据要发送给对端了,调用 close,这导致服务器端也发送一个 FIN 段到对端。 (4) 客户端接收到 FIN 后,回复 ACK 进行确认。 注意: 执行主动关闭的一方既可以是客户端,也可以是服务器,这两者之间是对等的。 通常断开连接需要 4 个 TCP 段。但是有时候不一定是这样。某些情况下,步骤 1 中的 FIN 段会随着数据一起发送到对端;另一种情况,步骤 2 和步骤 3 有可能被合并成一个 TCP 段 为什么是四次挥手? 实际上,这是 TCP 的半关闭(half-close)特性所造成的。 因为 TCP 连接是全双工的(数据在两个方向上可以同时传递),因此每个方向就必须能够单独的关闭。就比如客户端执行了半关闭操作后,只是通知服务器它没有数据要发送了,并不代表它不能接收数据。因此,只要服务器还没有主动关闭,就能够向客户端继续发送数据。也就相当于在步骤 2 和 步骤 3 之间,服务器仍然能够向客户端发送数据。 四次挥手为被动关闭的一方提供了很大的伸缩空间,让被动关闭一方有机会继续向主动关闭一方发数据。如果TCP 协议标准要求步骤 2 和 步骤 3 合并成一个步骤,这种伸缩空间就没有了,也就是说只要有一端关闭了,另一方就没有机会继续发送数据。 应用层如何知道对端已经调用close? 当read(socketfd,buffer,n)返回0时代表对端已经调用close server端调用了close(soketfd)函数 server调用了close(fd,SHUT_WR),关闭写连接,半关闭 【注意】 在 Linux 编程学习笔记中讲网络编程的时候,我们关闭连接用的都是函数 close. 任何一端使用函数 close 进行关闭,实际上就直接把全双工两个方向的连接全部关闭了。如果只想关闭一端,只能使用函数 shutdown 来关闭一个方向的连接。 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 17:27:29- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |