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服务器的连接。
作者|车小胖谈网络|公众号