| |
|
开发:
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通信过程理解 |
最近在测试TCP通信的时候偶然发现挥手关闭连接的时候只进行了3次挥手,所以有必要详细了解下TCP通信的过程。 相关概念? ? 序列号Seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。 ? ? 确认号Ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。 ? ? 确认标识ACK:占1位,仅当ACK=1时,确认号才有效;ACK=0时,确认号无效。 ? ? 同步标识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小写的单词表示序号。以下是常用的标识符:
TCP的三次握手过程理解第一次握手:建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认; 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RCVD状态; 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。 TCP数据传输过程理解
TCP的四次挥手过程理解?1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。 常见问题总结
? ? ? ? 因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到Server端所有的报文都发送完,才能发送FIN报文,因此需要四步挥手。当然也并不总是四次挥手,当Server端收到FIN报文后如果没有需要发送的数据报文,中间的FIN和ACK可以合并一起进行发送,此时就是3次挥手。 2.为什么不能用两次握手进行连接? ? ? ? ? 3次握手需要完成两个重要的功能,既要双方作好发送数据的准备工作(双方都知道彼此已准备好),也需要双方就初始序列号进行协商一致,这个序列号在握手的过程中被发送和确认。 ? ? 如果只进行两次握手,可能会造成死锁。考虑计算机S和C之间的通信,假定客户端C给服务器端S发送一个连接请求SYN,S收到了这个SYN,并发送了确认应答ACK。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据了。此时S对C的连接确认应答ACK如果在传输中丢失,C将不知道S是否已准备好,也不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分组,只等待连接确认应答分组。而S在发出的数据分组超时后,重复发送同样的分组。这样就形成了死锁。 3.为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSED状态?? ? ? ? ? 虽然按道理讲,四个报文都发送完毕,可以直接进入CLOSED状态,但是网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复时,该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接 4.如果已经建立了连接,但是客户端突然出现故障了怎么办? ? ? ? ? TCP有一个保活计时器,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没回应,服务器就认为客户端出了故障,接着就关闭连接。 |
|
网络协议 最新文章 |
使用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 22:59:57- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |