PS:通俗一点的解释都会在引用块中

Nothing is true, Everything is permitted.

0. 什么是TCP

TCP,全称Transmission Control Protocol,是一种面向连接、可靠的、基于字节流的单播协议。与我们常说的TCP/IP协议不同,TCP/IP是一个协议族,涉及到OSI模型中的网络层、应用层和应用层。而我们要聊的TCP就是在传输层的协议,现在应用的特别广泛的HTTP请求,就是基于TCP的。

1. 三次握手

所谓面向连接很好理解,就像我们要对远程服务器发出一个指令,首先我们需要登录上去。这个登录就是一个连接的过程。

在做数据交换之前,通信双方必须在彼此建立一条连接。也就是通信双方都维护了一份对方的信息,比如IP地址和端口号。说到建立连接,就不得不提到经典的三次握手和四次挥手。

1.1 为什么不两次握手

三次握手让通信双方都明确有一个连接正在建立,也为了确保客户端和服务器同时具有发送接收的能力。而两次握手做不到这一点。我们现在从另外一个角度来看一下三次握手,那就是为什么要三次握手?我两次握手它不香吗?让我们用一段对话来模拟如果真的采用两次握手,会带来什么问题。

朋友:喂,喂?听得到吗

你:听得到…你声音能不能小点

这就是两次握手。

按照人的逻辑来说,这已经是一次正常的对话了是吧,下一步难道不是建立连接吗?说下一步之前,需要先了解做三次握手的目的是什么。三次握手让通信双方都明确有一个连接正在建立,也为了确保客户端和服务器同时具有发送接收的能力。

我们来分析一下上面的那段对话。

朋友问你能不能听到,说明朋友具有发送能力;你听到了朋友的问题,说明你具有接收能力

如果只有两次握手,问题在哪儿呢?

站在朋友的角度,他知道你同时具有发送接收能力

但站在你(服务器)的角度,你只知道朋友具有发送能力,因为你不知道你发的声音能不能小点,他到底有没有收到

服务器不清楚客户端是否有接收能力的情况下,就算数据包真的发出去了,但无法知道客户端是否收到了数据。这样的就是不可靠的连接了。

而且,真实的网络传输中,出现网络延迟是常有的事,如果客户端发送了请求建立连接的数据包,由于网络延迟,数据包没有到达,客户端又发了一次,服务器收到之后建立了连接。

但是当前的连接关闭后,由于网络延迟的没有到达的包到了服务器,服务器又建立了连接,但是此时客户端已经断开了,这样就白白浪费了服务器的资源。

如果觉得上面的例子还是不能让你理解, 为什么两次握手不行。请看下面这个终极例子。

朋友:快借我点钱,XX宝账号123XXXXXXXX

你:好的, 你的帐号是123XXXXXXXX吗

。。。。。。(无应答)

你的内心:??????

如果你是被借钱的那个,你敢把钱转过去吗?


0341fda0555dc92b70a2ea4874115d5b

简单总结一下两次握手所带来的问题:不可靠,还会造成网络资源的浪费。

1.2 三次握手的过程

上面我们讨论了为什么要三次握手,接下来我们用几个专业术语来解释一下三次握手的过程。

  • 服务器开始监听某个端口,此时服务器进入了LISTEN状态

  • 客户端最初是CLOSED状态,然后向服务器发送一个SYN标志位的数据包,主动发起连接。客户端变成SYN-SENT状态

  • 服务器接收到客户端的SYN数据包,通过标志位知道了客户端想要建立连接。于是回了客户端一个SYN和ACK,表示收到了请求。服务器的自身状态变为了SYN-RCVD

  • 客户端收到了服务器的ACK,表示服务器知道了客户端想要建立连接。然后客户端再给服务器回了一个ACK表示自己收到了(或者说能够收到)服务器的消息,发送完这个ACK后,客户端的状态变成了ESTABLISH

  • 服务器收到了客户端的ACK,服务器的状态也变成ESTABLISH


2. 四次挥手

2.1 模拟四次挥手

老规矩,还是让我们用一段对话来模拟TCP的四次挥手。

场景,你跟你的朋友们正在外面high

你:你们继续玩,我就先走了,明天还要上班(第一次)

老铁:(老铁看到你在跟他说话且从你说的话中知道你要走了,老铁也用肢体语言告诉你他知道你要走了)(第二次)

老铁:那好吧, 路上注意安全哈 (第三次)

你:好的,下次再约 (第四次)

这就是通俗版本的四次挥手的解释,下面从专业的角度来看看。

2.2 四次挥手的过程

我们来看一下完整的流程。

  • 最初,客户端和服务器都处于ESTABLISH状态

  • 客户端想要断开连接,便主动向服务器发送标志位为FIN的数据包。发送之后客户端的状态变为FIN-WAIT-1,同时客户端也变成了半关闭状态,即无法向服务器发送数据包了,只能接收来自服务器的数据

  • 服务器收到客户端的FIN数据包,状态变为CLOSE-WAIT,并回给客户端一个表示确认的数据包ACK

  • 客户端收到了ACK之后,状态变为FIN-WAIT-2

  • 然后,服务器向客户端发送FIN数据包,服务器状态变为LAST-ACK

  • 客户端收到FIN数据包,客户端状态变为TIME-WAIT。然后回一个确认数据包ACK给服务器

  • 然后客户端等待2MSL,如果在这段时间内,没有收到服务器重发的消息,说明服务器收到了ACK

  • 四次挥手到此结束,连接断开



我们再来模拟一次刚刚的场景。

场景,你跟你的朋友们正在外面high

你:你们继续玩,我就先走了,明天还要上班(第一次)

老铁:(老铁喝high了,反射弧无限延长)

你肯定得再说一次啊,给朋友说你要走了,于是你又说了一次。

你:你们继续玩,我就先走了,明天还要上班(第一次)

老铁:(老铁喝high了,反射弧无限延长)

。。。。。。

如此反复

实际情况是,如果是两次挥手,也就是把服务器给客户端的ACK和FIN合并为同一个,如果此时网络出现了延迟,站在客户端的角度来看,客户端会认为刚刚发送的FIN报文并没有到达服务器,于是会在再重新发送一次。如果延迟的时间较长,那么客户端将会一直重新发送FIN的TCP报文。

2.3 对比分析

结合抽象和具体的四次挥手,其实就很好理解了,我们用一个表格来总结一下。

描述状态 实际情况
你和你的朋友在外面high 客户端和服务器建立了连接
你和朋友说你要走了 客户端主动向服务器发送FIN,客户端状态变为FIN-WAIT-1
你的朋友听到了并理解了你要说的话,并通过肢体语言反馈给你他知道了 服务器收到FIN数据包,并回了一个ACK,服务器的状态变为CLOSE-WAIT。客户端收到ACK之后变为FIN-WAIT-2
你的朋友说“那好吧, 路上注意安全哈” 服务器向客户端发送FIN包,服务器变为LAST-CHECK。
你说“好的,下次再约” 客户端收到FIN包后状态变为TIME-WAIT。并回一个ACK给服务器。
你迟疑了一下,你的朋友并没有挽留你 客户端等待2MSL,如果没有收到服务器的重发消息,则说明服务器收到了ACK。
你离开了和朋友的聚会 四次挥手结束,连接断开

2.4 为什么要等待

MSL,即Maximun Segment LifeTime,报文最大生存时间。为什么在TIME-WAIT之后还需要等待2MSL呢?主要是两个原因,让我们结合例子来理解一下。

保证服务器收到ACK

假设你说了“好的,下次再约”。由于大家都在high,声音太大了。导致你的朋友没有听到你说的“好的,下次再约”这句话,然后你转头就走了。

如果你站在你朋友的角度,肯定会心里很不爽,好心提醒你,连句道别的话都没有?

这种情况就是服务器并没有收到客户端收到的ACK,站在服务器的角度,服务器并不知道客户端收到了自己发的FIN包。也就不会断开连接,但是客户端已经单方面的断开连接了。又造成了服务器的资源浪费,服务器也无法进入正常的关闭连接状态。

防止失效的数据包

同样,你说了”好的, 下次再约“后,你没有确认你的朋友是否听到了,扭头就走。你的朋友也喝多了,此时心里很不爽,骂了一句傻X。

这句话刚好被路过、站到了你刚刚站的位置上的哥们接住了,以为在说他,心里就很不爽,提着拳头就把你的朋友揍了一顿。

这种情况是指,客户端没有等待2MSL就直接断开,但是服务器此时仍然有些数据包需要发送,或者已经发了出去。但是数据包到了后,此时的端口已经被新的连接占用了,老的TCP报文就会与新连接的TCP报文冲突、混淆。

3. 结尾

后面如果我有时间,会继续尝试把枯燥的理论抽象成生活中一些简单的现象并且与专业的知识结合起来的文章风格,来帮助那些看理论知识很吃力的人。其实只要理解了整个思路,是不需要去死记硬背的。

如果文章中有不对的地方,还望各位大佬不吝赐教。

如果你觉得这篇文章对你有帮助,还麻烦点个赞关个注分个享留个言

也可以微信搜索公众号【SH的全栈笔记】,当然也可以直接扫描二维码关注


拜了个拜

【俗话说】换个角度理解TCP的三次握手和四次挥手的更多相关文章

  1. 你应该这么理解TCP的三次握手和四次挥手

    前言: TCP协议是计算机的基础,他本身是一个非常非常复杂的协议. 本文只是蜻蜓点水,将从网络基础以及TCP的相关概念介绍开始,之后再将三次握手,四次挥手这些内容来阐述. 最后介绍一些常见问题,并给出 ...

  2. 理解 TCP/IP 三次握手与四次挥手

    TCP建立连接为什么是三次握手,而不是两次或四次? TCP,名为传输控制协议,是一种可靠的传输层协议,IP协议号为6. 顺便说一句,原则上任何数据传输都无法确保绝对可靠,三次握手只是确保可靠的基本需要 ...

  3. 理解TCP/IP三次握手与四次挥手的正确姿势

    背景 注:以下情节纯属虚构,我并没有女朋友==. 和女朋友异地恋一年多,为了保持感情我提议每天晚上视频聊天一次. 从好上开始,到现在,一年多也算坚持下来了. 问题 有时候聊天的过程中,我的网络或者她的 ...

  4. TCP/IP三次握手与四次挥手的正确姿势

    0.史上最容易理解的:TCP三次握手,四次挥手 https://cloud.tencent.com/developer/news/257281 A 理解TCP/IP三次握手与四次挥手的正确姿势http ...

  5. TCP的三次握手与四次挥手理解及面试题

    TCP的三次握手与四次挥手理解及面试题(很全面) 转载自:https://blog.csdn.net/qq_38950316/article/details/81087809 本文经过借鉴书籍资料.他 ...

  6. TCP的三次握手与四次挥手详解

    TCP的三次握手与四次挥手是TCP创建连接和关闭连接的核心流程,我们就从一个TCP结构图开始探究中的奥秘  序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序 ...

  7. 【图解】给面试官解释TCP的三次握手与四次挥手-Web运用原理及网络基础

    作者 | Jeskson 来源 | 达达前端小酒馆 轻松了解HTTP协议 为什么要学习网络协议呢?为什么要学习计算机完了呢?显然这很重要,至少能够帮助你找到工作的原因之一,学习网络知识点太多太多,没有 ...

  8. TCP 的三次握手和四次挥手

    参考资料: 1.TCP的三次握手与四次挥手理解及面试题: 2.Http协议三次握手和四次挥手: 3.TCP通信的三次握手和四次撒手的详细流程(顿悟) 前置: 序号(也称序列号) - Sequence ...

  9. TCP的三次握手与四次挥手

    TCP的三次握手与四次挥手 一.TCP(Transmission Control Protocol 传输控制协议) TCP是面向对连接,可靠的进程到进程通信的协议 TCP是提供全双工服务,即数据可在同 ...

随机推荐

  1. 极简配置,业务上云只需 3min

    为了简化账号配置环节,实现本地一键开发部署,Serverless Framework 发布了微信扫码一键登录能力,支持用户在 Serverless Framework 环境扫码注册登陆,用户无需登录控 ...

  2. python通过ssh读写远程数据

    1.适用场景 需要读取(写)多台远程机器下的一个或多个文件,如果要通过 os.system('scp ......')来完成就必须配置免密登陆,比较麻烦 2.准备工作, 安装依赖 pip instal ...

  3. string 转化xml && xml转化为string

    一.使用最原始的javax.xml.parsers,标准的jdk api // 字符串转XML [java] view plaincopyprint? String xmlStr = \". ...

  4. 算法之匹配:KMP

    public static int getIndexOf(String str1, String str2) { if (str1 == null || str2 == null || str1.le ...

  5. Linux 账号管理及ACL权限设置,PAM模块简介

    有效群组与初始群组: groups:有效与支持群组的观察 newgrp:有效群组的切换,后面接群组名称 在passwd文件中记录的GID就是默认的GID,就是初始群组 /etc/passwd文件结构 ...

  6. python3下scrapy爬虫(第十卷:scrapy数据存储进mysql)

    上一卷中我将爬取的数据文件直接写入文本文件中,现在我将数据存储到mysql中,我依然用的是pymysql,这个很麻烦建表需要在外面建 这次代码只需要改变pipyline就行 来 现在看下结果: 对比发 ...

  7. 听《Sara》

    Sara这首歌太好听了,虽然没有清楚具体是唱什么,但我感觉是讲一个故事,很好奇,我找到了歌词. Sara 塞拉 鲍勃迪伦 I laid on a dune, I looked at the sky, ...

  8. VSAN磁盘扩容与收缩

    删除闪存盘后,整个磁盘组都会被删除 假如一个磁盘组里面只有一块HDD盘,删除此HDD盘,磁盘组也只接被删除 可以整体删除整个磁盘组

  9. org.apache.http.NoHttpResponseException

    org.apache.http.NoHttpResponseException 异常: org.apache.http.NoHttpResponseException: The target serv ...

  10. 92)PHP,cookie代码补充

    (1)Cookie值,仅仅支持字符串类型. (2)Cookie键,可以写成下标数组形式. beifen.php <?php /** * @第一个值是name * @第二个值是value * na ...