本文转载自程序员技术

今天看到这两幅图片,不禁哈哈大笑。互联网上很多段子或者笑话,其实最能引起笑果的往往来自于真实生活,而不是那些为了笑果而编造的段子。

微信真的会因为网络不好而造成信息的前后颠倒吗?

真的会。

为什么呢?

马化腾说微信就是一个邮箱,只是这个邮箱比较快,让你感受不到这是一个邮箱,而让你有一种即时通信的错觉。

微信这个邮箱是这么来工作的:

Alice登录微信服务器,认证身份,上线状态。这是一个基于TCP的长连接,安全加密。所谓长连接,就是Alice只要不是手机没电或者关机状态,这个长连接一直都是运行且双向可以通信的。这个负责登录的服务器,简称登录服务器。

Alice给Bob发了一段文字,“Are you kidding me?”敲回车。这段文字是通过上文的长连接发送的吗?

不是的。而是通过一个短连接发送的,这个短连接是Alice点开Bob头像才建立的,这是一个 TCP + MMTLS(安全加密)+ http封装的短连接。

然后这个消息就被短连接以http格式发出去了。这个消息是直接发给Bob的吗?

不是的,而是发给Bob的邮箱。

Bob的邮箱是在Bob的手机里、还是微信存储服务器里?

微信服务器。

这样做有什么好处呢?

假如Bob在飞机上,手机关机,Alice消息依然可以将消息发出。如果直接发给Bob手机,手机都关机了,那就压根无法建立连接,自然连消息都发不出。当然好处还有许多,比如Alice与Bob的手机都位于NAT设备的后方,他们之间的直接通信不一定100%成功。

如果Bob是在线状态,登录服务器会第一时间通过TCP长连接,通知Bob微信邮箱里有信,至于这封信存在邮箱的什么地方,这是一个http格式的链接。Bob微信会与链接所对应的存储服务器建立短链接,将消息下载并显示到本地窗口,然后关闭短连接。

如果Bob是离线状态,微信服务器其实也不急的,反正消息呆在存储服务器,不会飞的。等Bob下飞机上线了第一时间通知Bob微信就好了。

以上就是微信的工作流程。接下来讲为何微信会发生消息后发先至的情况?

微信每次敲完一段文字,点击“发送“,这个消息就触发了一次:

  • 短连接的建立

  • 消息的传输

  • 短连接的断开

这个是标准的三步曲。当你再次发一段文字时,又触发了一次三步曲。两次的三步曲是相互独立的。

在网络畅通时,Alice第一个消息很快就发到Bob的邮箱,并被Bob微信呈现在窗口里。

Alice第二个消息发出的晚,自然到达得晚,这是非常好理解的。

但是当网络不好时,第一个三步曲的消息报文不是那么幸运,丢了,然后Alice的手机一直在重传这个消息。Alice又发送第二个消息,运气特别好,没有丢,结果比第一个消息早到了几秒。

既然微信讲究及时通信,微信会第一时间通知Bob的微信,只是这个消息通知顺序,先是第二个消息,然后才是第一个消息。这样就造成了微信消息时序的颠倒。

最后,每一段消息内部文字并没有颠倒,对吗?

这就是TCP的功劳,因为短连接依然使用的是TCP做为传输协议,TCP最擅长做的就是保证每一个字节按照先后顺序到达。TCP是一个可靠协议,可以修复由于网络暂时的中断而造成的字节丢失。但是如果Alice向Bob邮箱上传信的时候,网络发生了长时间的中断,超出了TCP最大修复时间,这时微信会提示Alice,消息发送失败!

一幅图片引发的离婚大战相关推荐

  1. 蚂蚁、小鸟、大象 引发的面向对象问题

    当你看到了这样一幅图片,有蚂蚁.小鸟.大象,你能够想出它们的相同之处吗? 它们都会吃eat.喝drink,这些是行为上的共性:都有体重weight.状态status(比如睡觉.活动等),这些是状态上的 ...

  2. /var/lib/docker/overlay2/xxxxx no such file or directory docker文件删除引发的问题

    记一次误删引发的服务雪崩 K8s node节点磁盘报警,报警后我找到服务中占用磁盘最多的地方,在overlay2目录下,对下面的文件进行了删除   删除后,有状态服务先出现了问题,服务无法启动.停止. ...

  3. 由Node.js事件驱动模型引发的思考

    引言 近段时间听说了Node.js,很多文章表述这个事件驱动模型多么多么优秀,应用在服务器开发中有很大的优势,本身对此十分感性去,决定深入了解一下,由此也引发了一些对程序设计的思考,记录下来. 什么是 ...

  4. mongodb java 日志分析_记一次log4j与mongodb集成引发的问题分析

    问题背景 对项目中的关键应用调用链日志需要结构化得统一吐出到mongodb中,同时项目中日志输出使用log4j,故准备使用log4j的Appender直接集成mongodb的输出,同时mongodb采 ...

  5. bug诞生记——const_cast引发只读数据区域写违例

    对于C++这种强类型的语言,明确的类型既带来了执行的高效,又让错误的发生提前到编译期.所以像const这类体现设计者意图的关键字,可以隐性的透露给我们它描述的对象的使用边界.它是我们的朋友,我们要学会 ...

  6. linux中非法内存,Linux下数组非法访问导致内存破坏 —— 引发segmentation fault的原因...

    2012-02-05 wcdj 1, 调试时必需的栈知识 2, 数组非法访问导致内存破坏 调试时必需的栈知识 栈(stack)是程序存放数据的内存区域之一,其特征是LIFO(Last In First ...

  7. Opencv4测试报错00007FFB3253A9C0 (ntdll.dll)处引发的异常: 0xC0000005: 读取位置 0x0000000000000010 时发生访问冲突

    报错信息如下: 0x00007FFB3253A9C0 (ntdll.dll)处(位于 test1.exe 中)引发的异常: 0xC0000005: 读取位置 0x0000000000000010 时发 ...

  8. Sql Server 因为触发器问题导致数据库更新报错“在触发器执行过程中引发了错误,批处理已中止”的问题处理...

    在维护一个非常旧的项目时,由于该项目版本已经非常老了,而且在客户现场运行的非常稳定,更要命的是本人目前没有找到该项目的代码,为了处理一个新的需求而且还不能修改程序代码,于是决定从数据库入手,毕竟该项目 ...

  9. 互联网引发全面深刻产业变革

    2019独角兽企业重金招聘Python工程师标准>>> 当前,互联网已经渗透到社会生产生活各个方面,深刻改变着人类社会运行方式,加速着人类文明进步的步伐,开启了一个崭新的时代.互联网 ...

最新文章

  1. FTP之‘基础连接已关闭:服务器提交了协议冲突’错误探析
  2. build 之前执行task_一次NPM前端项目的CI-Build速度优化
  3. 前端笔记-通过jQuery获取input数据及html中name的使用
  4. 知道端口号如何查看应用位置
  5. 【转载】石油天然气常用单位换算
  6. vim 快捷键_VIM学习笔记 环绕字符编辑(surround)
  7. 《Effective Java 3rd》读书笔记——对于所有对象都通用的方法
  8. 江苏省计算机二级用英语,江苏省计算机二级考试(VB)最新大纲及要求(国外英语资料).doc...
  9. 实现日志文件直接导入数据库
  10. Kettle下载和安装
  11. 接口测试用例设计和sql注入
  12. 网吧无盘服务器进u盘启动,利用U盘启动在网吧免费上网
  13. 也致第一次安装Rime的你
  14. android 反编译 jadx,jadx gui下载 jadx(Android反编译gui工具) v0.6.1 官方版 下载-脚本之家...
  15. 面试B站,结果面试官牵着一条狗出来面试我....这是什么操作??
  16. linux下使用iso文件安装yum
  17. Hisat2-Stringtie-DESeq2复现Transcript-level expression analysis of RNA-seq experiments with ...
  18. Zoho 企业邮箱不可用修复方案
  19. 2022年股权转让怎么计算个人所得税
  20. 如何使用计算机处理文件,如何设置电脑自动清理文件

热门文章

  1. 专项---APP安全---Android APP安全测试内容
  2. 战地之王大逃杀手机吃鸡
  3. MIT制作迷你猎豹机器人 将机器人丢出去可以自动著陆
  4. python chicken()
  5. org.dom4j.DocumentException: Error on line 1 of document : Content is not allowed in prolog. Nested
  6. 2020李宏毅深度学习hw1
  7. 手机上传图片文件只能打开相机
  8. Dots Entity 删除
  9. 微信视频服务器能保存多久,微信视频动态保存多久(微信背景视频只能一天吗)...
  10. 微信趣味测评小程序独立版源码