脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

转自即时通讯网:http://www.52im.net/

1、引言

网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一。很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答。
本篇文章尝试使用动画图片的方式,来对这个知识点进行“脑残式”讲解(哈哈),期望读者们可以更加简单、直观地理解TCP网络通信交互的本质。
另外,社区里的另两篇文章《理论经典:TCP协议的3次握手与4次挥手过程详解》、《理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程》也是不错的入门文章,有兴趣可一并详读之。
友情提示:因本文gif动画较多,如果您的网速较慢,请耐心等候图片加载完成哦。

2、关于作者

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手_aa.png

钱文品(老钱):毕业于华中科技大学计算机科学与技术专业,互联网分布式高并发技术十年老兵,目前任掌阅科技资深后端工程师。熟练使用 Java、Python、Golang 等多种计算机语言,开发过游戏,制作过网站,写过消息推送系统和MySQL 中间件,实现过开源的 ORM 框架、Web 框架、RPC 框架等。

作者的Github: https://github.com/pyloque

3、系列文章

本文是系列文章中的第1篇,本系列大纲如下:

  • 《脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手》(本文
  • 《脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?》
  • 《脑残式网络编程入门(三):HTTP协议必知必会的一些知识》
  • 《脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)》
  • 《脑残式网络编程入门(五):每天都在用的Ping命令,它到底是什么?》

4、TCP三次握手:“Say hello!”

TCP 三次握手就好比两个人在街上隔着50米看见了对方,但是因为雾霾等原因不能100%确认,所以要通过招手的方式相互确定对方是否认识自己。
 

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手_1.gif

张三首先向李四招手(syn),李四看到张三向自己招手后,向对方点了点头挤出了一个微笑(ack)。张三看到李四微笑后确认了李四成功辨认出了自己(进入estalished状态)。

但是李四还有点怀疑,向四周看了一看,有没有可能张三是在看别人呢,他也需要确认一下。所以李四也向张三招了招手(syn),张三看到李四向自己招手后知道对方是在寻求自己的确认,于是也点了点头挤出了微笑(ack),李四看到对方的微笑后确认了张三就是在向自己打招呼(进入established状态)。

于是两人加快步伐,走到了一起,相互拥抱。

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手_2.gif

我们看到这个过程中一共是四个动作,张三招手--李四点头微笑--李四招手--张三点头微笑。其中李四连续进行了2个动作,先是点头微笑(回复对方),然后再次招手(寻求确认),实际上可以将这两个动作合一,招手的同时点头和微笑(syn+ack)。于是四个动作就简化成了三个动作,张三招手--李四点头微笑并招手--张三点头微笑。这就是三次握手的本质,中间的一次动作是两个动作的合并。

我们看到有两个中间状态,syn_sent和syn_rcvd,这两个状态叫着「半打开」状态,就是向对方招手了,但是还没来得及看到对方的点头微笑。syn_sent是主动打开方的「半打开」状态,syn_rcvd是被动打开方的「半打开」状态。客户端是主动打开方,服务器是被动打开方。

syn_sent: syn package has been sent
syn_rcvd: syn package has been received

5、握手完成:开始TCP数据传输

TCP 数据传输就是两个人隔空对话,差了一点距离,所以需要对方反复确认听见了自己的话。
脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手_3.gif

张三喊了一句话(data),李四听见了之后要向张三回复自己听见了(ack)。
如果张三喊了一句,半天没听到李四回复,张三就认为自己的话被大风吹走了,李四没听见,所以需要重新喊话,这就是tcp重传。
也有可能是李四听到了张三的话,但是李四向张三的回复被大风吹走了,以至于张三没听见李四的回复。张三并不能判断究竟是自己的话被大风吹走了还是李四的回复被大风吹走了,张三也不用管,重传一下就是。
既然会重传,李四就有可能同一句话听见了两次,这就是「去重」。「重传」和「去重」工作操作系统的网络内核模块都已经帮我们处理好了,用户层是不用关心的。

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手_4.gif

张三可以向李四喊话,同样李四也可以向张三喊话,因为tcp连接是「双工的」,双方都可以主动发起数据传输。不过无论是哪方喊话,都需要收到对方的确认才能认为对方收到了自己的喊话。

张三可能是个高射炮,连说了八句话,这时候李四可以不用一句一句回复,而是连续听了这八句话之后,一起向对方回复说前面你说的八句话我都听见了,这就是批量ack。但是张三也不能一次性说了太多话,李四的脑子短时间可能无法消化太多,两人之间需要有协商好的合适的发送和接受速率,这个就是「TCP窗口大小」。
网络环境的数据交互比人类之间的对话还要复杂一些,它存在数据包乱序的现象。同一个来源发出来的不同数据包在「网际路由」上可能会走过不同的路径,最终达到同一个地方时,顺序就不一样了。操作系统的网络内核模块会负责对数据包进行排序,到用户层时顺序就已经完全一致了。

6、TCP四次挥手:“Say goodbye!”

TCP断开连接的过程和建立连接的过程比较类似,只不过中间的两部并不总是会合成一步走,所以它分成了4个动作,张三挥手(fin)——李四伤感地微笑(ack)——李四挥手(fin)——张三伤感地微笑(ack)。

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手_5.gif

之所以中间的两个动作没有合并,是因为tcp存在「半关闭」状态,也就是单向关闭。张三已经挥了手,可是人还没有走,只是不再说话,但是耳朵还是可以继续听,李四呢继续喊话。等待李四累了,也不再说话了,朝张三挥了挥手,张三伤感地微笑了一下,才彻底结束了。

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手_6.gif

上面有一个非常特殊的状态time_wait,它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的持续时间是4分钟,4分钟后才会进入到closed状态,释放套接字资源。不过在具体实现上这个时间是可以调整的。

它就好比主动分手方要承担的责任,是你提出的要分手,你得付出代价。这个后果就是持续4分钟的time_wait状态,不能释放套接字资源(端口),这段时间内套接字资源(端口)不得回收利用。

它的作用是重传最后一个ack报文,确保对方可以收到。因为如果对方没有收到ack的话,会重传fin报文,处于time_wait状态的套接字会立即向对方重发ack报文。

同时在这段时间内,该链接在对话期间于网际路由上产生的残留报文(因为路径过于崎岖,数据报文走的时间太长,重传的报文都收到了,原始报文还在路上)传过来时,都会被立即丢弃掉。4分钟的时间足以使得这些残留报文彻底消逝。不然当新的端口被重复利用时,这些残留报文可能会干扰新的链接。

4分钟就是2个MSL,每个MSL是2分钟。MSL就是maximium segment lifetime——最长报文寿命。这个时间是由官方RFC协议规定的。至于为什么是2个MSL而不是1个MSL,我还没有看到一个非常满意的解释。
四次挥手也并不总是四次挥手,中间的两个动作有时候是可以合并一起进行的,这个时候就成了三次挥手,主动关闭方就会从fin_wait_1状态直接进入到time_wait状态,跳过了fin_wait_2状态。

7、本文小结

TCP状态转换是一个非常复杂的过程,本文仅对一些简单的基础知识点进行了类比讲解。关于TCP的更多知识还需要读者去搜寻相关技术文章进入深入学习。如果读者对TCP的基础知识掌握得比较牢固,高级的知识理解起来就不会太过于吃力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440194.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【HDU - 5452】Minimum Cut(树形dp 或 最近公共祖先lca+树上差分,转化tricks,思维)

题干: Given a simple unweighted graph GG (an undirected graph containing no loops nor multiple edges) with nn nodes and mm edges. Let TT be a spanning tree of GG. We say that a cut in GG respects TT if it cuts just one edges of TT. Since love…

Idea自带的工具打jar包和Maven打Jar包(SpringBoot工程)

1.Idea自带的工具打jar包 (1)点击菜单栏的File后选中Project Structure,接着按如下图所示操作: (2)点击“OK”按钮后会出现下图的界面,然后继续点击“OK”按钮 (3)现在开…

图解算法学习笔记(目录)

今天遇到一本好书,如下,书很薄,不到200页,有将近400张图片,算法介绍的很有趣。这也是我读的第三本袁国忠先生翻译的书,向两位致敬。 目录大致如下; 第1章:二分查找和大O表示法; 第…

【POJ - 3249】Test for Job(DAG线性求带负权的最长路,dp)

题干: Mr.Dog was fired by his company. In order to support his family, he must find a new job as soon as possible. Nowadays, Its hard to have a job, since there are swelling numbers of the unemployed. So some companies often use hard tests for …

图解算法学习笔记(二): 选择排序

目录 1)数组和链表: 2)选择排序算法: 3)小结 本章内容: 两种基本数据结构:数组和链表; 选择排序算法; 1)数组和链表: 数组是连续的内存单元,链表可以不连续; 链表…

【HDU - 5456】Matches Puzzle Game(数位dp,思维)

题干: As an exciting puzzle game for kids and girlfriends, the Matches Puzzle Game asks the player to find the number of possible equations A−BCA−BC with exactly n (5≤n≤500)n (5≤n≤500) matches (or sticks). In these equations, A,BA,B and …

图解算法学习笔记(三):递归

本章内容&#xff1a; 学习递归&#xff1b;如何将问题分解成基线条件和递归条件。 1) 每个递归函数都有两部分&#xff1a;基线条件(base case)和递归条件(recursive base)。例如&#xff1a;打印3...2...1 def countdown(i):print(i)if i < 0:returnelse:countdown(i…

Apollo自动驾驶入门课程第⑨讲 — 控制(上)

目录 1. 简介 2. 控制流程 3. PID控制 4. PID优劣对比 本文转自微信公众号&#xff1a;Apollo开发者社区 原创&#xff1a; 阿波君 Apollo开发者社区 9月26日 上周我们发布了无人驾驶技术的 规划篇&#xff0c;车辆基于高精地图&#xff0c;感知和预测模块的数据来进行这一…

Apollo自动驾驶入门课程第⑩讲 — 控制(下)

目录 1. 线性二次调节器 2. 模型控制预测 3. 总结 本文转自微信公众号&#xff1a;Apollo开发者社区 原创&#xff1a; 阿波君 Apollo开发者社区 昨天 Apollo自动驾驶课程马上进入尾声&#xff0c;在无人驾驶技术控制篇&#xff08;上&#xff09;中&#xff0c;具体讲解了最…

图解算法学习笔记(四):快速排序

目录 1&#xff09; 示例1&#xff1a; 2&#xff09;快速排序 3) 再谈大O表示法 4&#xff09;小结 本章内容&#xff1a;学习分而治之&#xff0c;快速排序 1&#xff09; 示例1&#xff1a; 假设你是农场主&#xff0c;有一小块土地&#xff0c;你要将这块地均匀分成方…

图解算法学习笔记(五):散列表

目录 1&#xff09;示例1&#xff1a; 2&#xff09;散列函数 3&#xff09;应用案例 4&#xff09;冲突 5&#xff09;性能 6&#xff09;小结 本章内容&#xff1a; 学习散列表&#xff0c;最有用的数据结构之一。 学习散列表的内部机制&#xff1a;实现、冲突和散列函…

图解算法学习笔记(六):广度优先搜索

目录 1&#xff09;图简介 2&#xff09;图是什么 3&#xff09;广度优先搜索 4&#xff09;实现图 5&#xff09;实现算法 6&#xff09;小结 本章内容; 学习使用新的数据结构图来建立网络模型&#xff1b; 学习广度优先搜索&#xff1b; 学习有向图和无向图…

图解算法学习笔记(七):狄克斯特拉算法

目录 1&#xff09;使用狄克斯特拉算法 2&#xff09;术语 3&#xff09;实现 4&#xff09;小结 本章内容; 介绍加权图&#xff0c;提高或降低某些边的权重&#xff1b; 介绍狄克斯特拉算法&#xff0c;找出加权图中前往X的最短路径&#xff1b; 介绍图中的环…

【HDU - 5477】A Sweet Journey(思维,水题)

题干&#xff1a; Master Di plans to take his girlfriend for a travel by bike. Their journey, which can be seen as a line segment of length L, is a road of swamps and flats. In the swamp, it takes A point strengths per meter for Master Di to ride; In the f…

图解算法学习笔记(八):贪婪算法

目录 &#xff08;1&#xff09;背包问题 &#xff08;2&#xff09;集合覆盖问题 &#xff08;3&#xff09;NP完全问题 &#xff08;4&#xff09;小结 本章内容&#xff1a; 学习如何处理没有快速算法的问题&#xff08;NP完全问题&#xff09;。学习近似算法&#xff…

图解算法学习笔记(九):动态规划

目录 &#xff08;1&#xff09;背包问题 &#xff08;2&#xff09;最长公共子串 &#xff08;3&#xff09;小结 本章内容&#xff1a; 学习动态规划&#xff0c;它将问题分成小问题&#xff0c;并先着手解决这些小问题。学习如何设计问题的动态规划解决方案。 &#xff…

Java(win10安装jdk,第一个hello world)

Java 第一步 &#xff1a;安装jdk 推荐默认安装。&#xff08;安装到C盘&#xff09;第二步 &#xff1a;配置jdk环境 JAVA_HOME C:\Program Files\Java\jdk1.8.0_191 JDK的安装路径 Path&#xff1a; C:\Program Files\Java\jdk1.8.0_191\bin JDK下bin目录的路径 &#xf…

#pragma 详解

#pragma 求助编辑 pragma - 必应词典美[prɡmə]英[prɡmə]n.〔计〕杂注网络编译指示&#xff1b;显示编译指示&#xff1b;特殊指令 百科名片 在所有的预处理指令中&#xff0c;#Pragma 指令可能是最复杂的了&#xff0c;它的作用是设定编译器的状态或者是指示编译器完成一些…

1.绪论

目录 &#xff08;1&#xff09;C语言传值与传地址变量 &#xff08;2&#xff09;算法效率的度量 &#xff08;3&#xff09;基本操作 &#xff08;4&#xff09;主函数 主要由实现基本操作和算法的程序构成。这些程序有6类&#xff1a; 数据存储结构&#xff0c;文件名第…

(ECC)椭圆曲线加密算法原理和C++实现源码

目录 &#xff08;1&#xff09;ECC加密原理&#xff1a; &#xff08;2&#xff09;编译生成LibTommath静态库 &#xff08;3&#xff09;ECC源码 今天介绍一下利用LibTommath数学库实现椭圆曲线加密算法的原理和源码。 &#xff08;1&#xff09;ECC加密原理&#xff1a;…