作者|张宇鹏,单位:中国移动智能家居运营中心实验室.中国移动移动管家业务提供基于视频的场景化安防服务,支持接入工控机、门锁、猫眼等泛安防智能硬件。用户可通过和家亲APP视频播放等功能,实现远程看护、设备对讲、监控等功能。为实现上述功能,IPC等设备需要使用流媒体传输协议发送摄像头采集的音视频媒体流,APP通过流媒体传输协议获取媒体流。目前市面上常见的流媒体传输协议有:RTMP、WebRTC、QUIC、P2P、SRT等,手机管家使用的流媒体传输协议主要有P2P和SRT。关于这两个协议,笔者打算用两篇文章来介绍一下。本文首先介绍P2P协议。1什么是P2P?简单来说,P2P就是一种设备之间直接点对点通信的方式,不需要通过中间服务器转发。那么非P2P是如何通信的呢?下面以微信通信为例,简单介绍一下:图1从图1可以看出,小明通过微信给小红发了一条消息,消息的真实流向路径是:小明->腾讯服务器->小明红。那么问题来了,为什么消息先走腾讯服务器,而不是直接:小明->小红?答:大概率是小明的手机无法在网上直接找到小红的手机。怎么理解这句话?请参考图2和图2。我们都知道在网络世界中,某个设备是由其IP地址唯一确定的,但是由于IPv4地址数量有限,很多设备实际上并不能获得唯一的IP地址(publicnetworkaddress),而是利用NAT(NetworkAddressTranslation)技术获取一个内网地址,多个内网地址共享一个公网地址实现上网。家庭中常见的内网地址是:192.168.X.X。公网地址是唯一的,但是内网地址不是唯一的,所以如果只知道一个设备的内网IP地址,是找不到对应的设备的(除非刚好在同一个内网环境),这就是为什么小明的手机大概率是网上查不到小红手机的。由于腾讯服务器有自己的公网地址,小明和小红都可以通过这个公网地址找到腾讯服务器,然后通过腾讯服务器这个中介,小明和小红就可以进行通信了。从图2我们还可以发现,路由器A的WAN口连接小明手机的IP地址(公网地址)为:36.23.223.162;路由器B的WAN口连接小红手机的IP地址(公网地址)为:183.129.184.211。如果小明知道自己的公网IP地址,告诉小红(反之亦然),就可以跳过腾讯服务器,直接连接对方。这其实就是P2P的技术原理。2、为什么要用P2P?使用P2P有很多好处,从不同的角度可以得出不同的答案。从设备厂商的角度来看,如果他们的设备之间可以实现P2P,可以降低中转服务器的流量成本,尤其是在数据量很大的时候,P2P节省流量的优势更加明显,从而降低运营成本.从技术角度来说,P2P直接跳过了服务器传输,所以只要连接成功,理论上它的传输速度会更快。图33如何实现P2P?从图2的描述我们知道,如果设备能够知道自己的公网IP地址和端口,并告诉对方,就可以实现P2P通信。因此,要实现P2P通信,必须解决以下两个问题:如何获取自己的公网IP地址和端口如何将获取到的公网IP地址和端口告诉对端3.1NAT原理关于如何获取自己的IP公网地址和端口,可以参考浏览器访问百度搜索引擎的过程,如下图所示:图4中路由器下连接了4台设备:ABCD,假设这4台设备通过浏览器(假设它们都使用内部80端口),那么在路由器上会生成一个NAT映射表,浏览器返回的数据在经过路由器时会通过这个映射表找到对应的内部设备。从表中可以看出,这些设备映射的外网IP地址相同(即路由器的外网IP地址),只是端口不同。因此,浏览器返回数据时,可以通过IP+端口确定唯一设备(其实这也是NAT技术可以让多台设备只用一个公网地址独立上网的基本原理)。同理,如果此时小明要与设备A通信,那么小明只需要向设备A映射的公网地址信息发起连接:36.23.223.162:8081即可。因此,如果能够将内网设备通过NAT映射到公网,并且能够得到映射后的公网IP地址和对应的端口号,那么P2P通信的第一步就实现了。要实现内网设备到公网地址的映射,除了主动访问知名网站外,还可以通过STUN协议来实现。3.2STUN协议图5STUN协议如图5所示:设备通过向公网上的STUN服务器发送请求,获取自己的公网地址信息。同样,这种协议或方法允许路由器在内部和外部网络映射时留下一个“洞”,通常称为“打洞”。而如果外网的主机可以通过这个“洞”与内网的主机进行通信,就说明“这个洞被钻成功了”。3.3信令服务器可以通过STUN协议获取设备自身的外网IP地址和端口,这只是P2P通信的第一步。第二步是如何告诉对方你的外网IP地址和端口。通常我们需要使用信令服务器来实现。一般的解决方案如图6所示:图6第一步:IPC通过STUN协议获取自己的公网地址信息:36.23.223.162:8081;第二步:IPC将自己的地址信息发送给信令服务器,信令服务器将地址信息转发给“和家亲APP”;第三步:“和家亲APP”获取对端地址信息后发起连接;由于路由器已经有IPC地址映射,发起的连接会转发给IPC设备,至此“和家亲APP”与IPC的P2P连接就实现了。关于信令服务器,这里需要说明一下。一般来说,设备在启动时,会主动连接信令服务器,然后与信令服务器保持长连接;该应用程序还将与信令服务器保持连接;IPC与APP之间的通信可以通过信令服务器实现。服务器使用的协议是websocket。4展开图6中的几个步骤有助于快速理解P2P的原理,但也省略了很多内部细节。本章将补充一些剩余的知识点。想一个问题:通过STUN协议获取到的公网IP地址和端口,对端能连接成功吗?显然答案是否定的。否则就没有“打孔成功率”的概念。为了理解这一点,首先需要了解NAT类型。4.1NAT类型目前常见的NAT可以分为4种类型:FullConeIPRestrictedConePortRestrictedConeSymmetrical在这4种类型中,NAT类型越靠后越难穿越。4.1.1完整锥体完整锥体的特点:一旦一个孔被成功钻出,所有知道该孔的主机都可以通过它与内网主机通信。4.1.2IP限制锥型IP限制锥型特点:IP限制锥型比全锥型严格。打洞成功后,只有打洞成功的外网主机才能通过该洞与内网主机通信,而其他外网主机即使知道这个洞也无法通信。4.1.3端口限制锥端口限制锥特点:端口限制锥比IP限制锥更严格。打孔成功后,除了检测IP地址外,还需要检测端口号。只要不满足两者之一,就无法通过孔进行通信。4.1.4对称全锥特征:内部主机每次访问不同的外部主机,都会产生一个新的孔。前三种锥体类型使用相同的孔。不同NAT类型的路由器的遍历表如下:因此,在前面的例子中,我们实际上假设路由器的NAT类型默认为fullcone。但实际上,我们需要处理除fullcone之外的其他类型的路由器。4.2TURN协议当两端路由器的NAT类型为:(端口限制锥型,对称型)或(对称型,对称型)时,不能使用STUN协议穿越,需要使用TURN协议此时。TUAN协议只是简单的数据转发。两台内网主机分别将内容发送给TURN服务器,TURN服务器分别将内容转发给对端,实现通信。这里我就不细说了。5小结P2P打洞的大致过程主要有以下两步:内网设备通过STUN/TURN协议获取自己的内外网地址信息;相关地址信息通过信令服务器发送给对端,客户端得到相应的地址信息后,尝试连接。在实际过程中,进行P2P打洞的设备不仅要获取外网的地址信息,还要获取内网的地址信息,还要获取TRUN服务器分配的地址信息,生成候选地址对,并且候选地址对也具有连接优先级。层次的概念,一般来说,所有的候选地址对都会尝试连接。由于P2P协议涉及的内容非常多,因此不仅要了解底层网络原理,还要了解STUN和TUAN协议的内容。而且,P2P协议打洞成功与否的关键往往与设备所在的网络环境有关。如果设备和APP在对称路由器下,打洞成功的概率会很低,而且由于P2P流程比较长,不了解其原理的开发者很难定位。基于以上原因,中国移动智能家居运营中心的移动管家设备升级为全新的流媒体传输协议——SRT。但是这并不妨碍我们了解P2P的实现原理。关于SRT协议的介绍,敬请期待下一篇。
