QQ消息是如何到达接收方的?看完这个你就明白了

news2024/12/27 12:08:15

A通过QQ给异地的B发了条消息,直到B收到了消息,中间经历了怎样的过程?

北京的A通过QQ给深圳的B发了一条消息,B在QQ上接收到了消息,从A点击发送开始,到B看到消息结束,中间过程是如何实现的?中间可能涉及消息类型的转换,QQ,ISP等角色起到了什么作用;物理元件或设备的功能体现,网卡,路由器,网线,电线发挥了什么作用;信号的转换等等。不是单纯的想知道七层结构下是如何实现的,而是整个过程是如何实现的,其中可能包含网络,通信,物理相关的知识,向专业的老师请教,希望了解的老师能不吝解惑。

如果把QQ所有的服务器高度概括为一台服务器,问题则简化为:

  • 主机A与QQ服务器的通信
  • QQ服务器与主机B的通信

主机A(小明)要发消息给QQ服务器,主机A(小明)知道QQ服务器的IP地址吗?

这个没有问题,QQ软件里提前配置了QQ服务器列表。

假设主机A(小明)到达了QQ服务器,此时QQ服务器怎么办?

主机B(小美)如果在线,直接把消息发给小美。但是QQ服务器不对消息保存备份,不符合审查规范。

主机B(小美)如果不在线,先存储起来,等小美上线再把消息发给小美。

所以,QQ消息无论对方(接收方小美)在不在线,都是可以发出的,因为这纯粹是主机A(发送方小明)与QQ服务器之间的通信。

既然要存储用户的QQ消息,自然对用户ID有唯一性(Unique)的要求,这个全局唯一的ID就是QQ号码,QQ号码是唯一识别用户的ID。

可以将QQ服务器看成一个邮件服务器,每个登录用户都有一个邮件账号(QQ号),QQ服务器收到用户的消息,根据接收人的QQ号码,将消息保存在数据库里。一旦要从数据库里提取消息,只要使用接收人的QQ号码作为查询条件,即可将消息读出。

当然,QQ服务器不可能真的就一台,而是分布在多地的多台服务器列表。这个在QQ软件里会预配置。主机A(小明)与优先使用哪台服务器,这个可以尝试Ping服务器列表,看看谁的延迟最小,优先选择最佳服务器。

北京的主机A(小明)与深圳的主机B(小美)登录的QQ服务器可能不是一台,而是多台。假设收到小明消息的是服务器A,而小美则登录在服务器B上。怎么能让服务器A知晓小美是挂在服务器B上,从而服务器A将消息转发给服务器B,服务器B再转发给小美?

这就需要一台中心服务器C,每当用户登录服务器时,登录服务器会将用户QQ号与服务器的IP地址发到中心服务器C上,这样服务器C就会有QQ号,登陆服务器对应表。

服务器A只要查询一下服务器C,即可获得服务器B的IP地址,即可建立安全加密连接,即可将发给小美的消息转发给服务器B,再转发给小美。

毕竟QQ属于即时通信,将延迟降低到最小值是一个重要的指标。所以为了最大限度降低延迟,上文中的各个服务器之间的安全加密连接,用户消息到来之前早已建立,用不着再花额外的时间建立。甚至用户QQ号与服务器的映射表数据库都可以周期性从C同步到各个QQ服务器。

上文的通信,都是使用IP报文作为运输工具,采用IP路由寻找目的地,这些都是通用的。唯一需要注意的是,用户与QQ服务器之间的通信,需要NAT。为了使得QQ服务器能将消息及时推送给用户,NAT表需要存在,不能因为没有流量刷新而老化删除,这样QQ客户端就无法及时收到消息推送。

为了避免NAT表被删除,QQ客户端会周期性发送心跳,从而刷新NAT表,QQ服务器收到心跳包,几乎不需要处理(更新一下用户依然在线的状态),就把心跳包扔了。

至于QQ打电话、QQ传输文件,原理是相似的,仅有细微的差别,通信在两个客户端之间端到端完成(建立连接),中间需要QQ服务器作为中介介入。而QQ消息,两个客户端之间压根没有建立连接,它们只维持和QQ服务器的连接。

作者|车小胖谈网络|公众号

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

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

相关文章

.Net Core Restful Api 版本区分第一种

前言:在我们进行Web Api开发时,版本的区分,是必须要考虑的,涉及到我们的版本发布,切换等,如何从旧版本无缝的切换到新版本? 下面,我们通过使用[ApiVersion]特性,实现两个…

超详细的学习笔记:CSS定位装饰(附代码示例)

笔记参考b站网课:【前端开发入门教程,web前端零基础html5 css3前端项目视频教程】https://www.bilibili.com/video/BV1Kg411T7t9?p124&vd_source06e5549bf018e111f4275c259292d0da 目录 一、网页常见布局方式 1、标准流 2、浮动 3、定位 二、定…

软件鉴定测试报告需要哪些材料?

软件鉴定测试报告是对软件产品进行功能、性能和安全等方面的测试和评估后所生成的报告。软件鉴定测试报告作为软件质量的重要指标,为软件的发布和应用提供可靠的依据。以下是软件鉴定测试报告中常见的材料内容: 1. 软件测试计划:包括测试目的…

UncategorizedSQLException 报错

85、UncategorizedSQLException 报错 出现问题的原因: 本身是没有这个问题的,后来服务器上的一张表,被误删了,重新创建之后,就出现了这个问题 org.springframework.jdbc.UncategorizedSQLException: ### Error upd…

C++—类和对象

文章目录 1 类2 对象2.1 创建对象2.2 对象的操作2.3 构造函数2.4 析构函数 3 静态成员4 this指针5 友元 一切我们研究的事物,都可以叫做对象。对象具有状态,操作和行为。通常用一个数值来描述对象的状态。对象的操作用于改变对象的状态。对象和对象的操作…

BlueZ 开发学习指南(一) --- D-Bus介绍

BlueZ 开发学习指南(一) — D-Bus介绍 一、 BlueZ与D-Bus简介 Linux使用的蓝牙协议栈是Blue Z,不同于我们以往的开发方式,Blue Z提供的API 并不是通过头文件这样的形式, 而是通过D-Bus的方式来提供的。 Blue Z提供的是…

AutoDL 训练stable-diffusion lora模型

1.创建镜像实例 2. 启动实例 3.启动服务 4.配置参数 4.1 基础模型选择 4.2 文件路径设置 5.点击打印训练信息 6.训练模型(点击Train model)

C++ 迭代器的设计与使用

C 迭代器是一种用于访问容器(例如数组、向量、列表等)元素的工具。它们允许我们以一种统一的方式遍历和操作容器中的数据,而不用关心容器内部数据结构的细节 C 迭代器 std 重要函数 std::begin 和 std::endstd::advance(iter,n)向前移动…

从零开始,用Python编写EA实战指南

在外汇交易领域,EA(Expert Advisor)是一种基于计算机程序的交易策略,被广泛应用于机器人化交易和量化交易。Python作为一种高效、灵活的编程语言,被越来越多的投资者用于编写EA和数据分析。本文将提供一份从零开始&…

Postgresql在哪里使用列统计信息?

对pg_statistic表的查询都是走syscache的,要找到所有使用列统计信息地方,遍历系统表索引即可 enum SysCacheIdentifier {...STATEXTDATASTXOID,STATEXTNAMENSP,STATEXTOID,STATRELATTINH,... }下面是最常用的STATRELATTINH索引场景,即 Sear…

行业追踪,2023-07-13,新样式来了,更清晰地追踪行业趋势

自动复盘 2023-07-13 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…

利用 Elasticsearch、ESRE、LLM 和 LangChain 加速制药行业的研发 — 第 1 部分

作者:Valerio Arvizzigno, Dimitri Marx, Francesco Di Stefano 这是一篇通过生成式 AI/LLM、自定义模型和 Elasticsearch 相关性引擎 (ESRE​​) 支持制药行业更快的药物创新和发现的综合指南。更快的药物发现带来有前途的候选药物是制药行业的主要目标。 为了支持…

Mysql表空间、段、区、页的关系

提示:mysql表空间、段、区、页的关系详细描述 文章目录 表空间-TABLE SPACE1 查看 表空间相关参数段(segment)区(extent)页(page) 表空间-TABLE SPACE 从 InnoDB 逻辑存储结构来看,…

顺序表 --- C语言实现

目录 1.线性表 2.顺序表 2.1 概念和结构 2.2 接口实现 2.3 数组相关面试题 2.4 顺序表的问题及思考 1.线性表 什么是线性表 : 线性表(linear list)是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常…

Vue3 概述

文章目录 Vue3 概述概述Vue3对比Vue2优势使用create-vue创建项目概述创建项目目录结构 使用vue-cli创建项目概述创建项目目录结构 Vue3 概述 概述 Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript…

自定义指令directives:防抖,节流,element-ui的无限滚动在el-table上使用的封装

vue官网对于自定义指令的介绍 添加链接描述 除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM…

分布式事物【RocketMQ事务消息、Docker安装 RocketMQ、实现订单微服务、订单微服务业务层实现】(八)-全面详解(学习总结---从入门到深化)

目录 可靠消息最终一致性分布式事务实现_RocketMQ事务消息 可靠消息最终一致性分布式事务实战_案列业务介绍 数据库表设计 可靠消息最终一致性分布式事务实战_Docker安装 RocketMQ 部署RocketMQ的管理工具 可靠消息最终一致性分布式事务实战_实现订单微服务 可靠消息最终一…

分层解耦-IOCDI-DI详解

目录 Bean注入 小结 依赖注入的注解 Resource和Autowired区别 Bean注入 Autowired注解,默认是按照类型进行依赖注入,如果存在多个相同类型的bean就会报错 解决方案 Primary(设置bean的优先级) Qualifier(通过bean…

简单版本视频播放服务器V1

一直想做个家用版本的视频播放器,通过这个可以实现简单的电脑,通过浏览器就是可以访问电脑里面的视频,通过手机,平板等都是可以访问自己的视频服务了 后端代码: package mainimport ("fmt""io/iouti…

2023年7月13日 星期四 Linux驱动作业

1.使用platform驱动实现代码实现如下要求 a.应用程序通过阻塞的io模型来读取number变量的值 b.number是内核驱动中的一个变量 c.number的值随着按键按下而改变(按键中断) 例如number0 按下按键number1再次按下按键number0d.在按下按键的时候需要同时将1ed1的状态取反 t e.驱动…