大家好,又见面了,我是你们的朋友全栈君。
无论哪种Peer,使用的P2P协议都是UDP,因为对NAT打洞来说,UDP的打洞成功率比TCP高。据闻有不信邪的尝试过TCP,最后还是回归UDP。也有说使用UPnP的,这个主要依赖于路由设备,可控性不够。
P2P Client使用STUN协议探测NAT类型,要准确探测NAT类型,需要在STUN Server上部署两个网卡,然后客户端按照RFC3489规定的标准流程执行探测。以下是P2P Client使用的NAT类型探测状态机,基本遵照RFC3489的流程。
搜狐视频P2P有以下几类Peer:
我们破解了rtmfp协议后封装的库
)的程序,通过rtmfp协议互通;移动端的P2P Client只能作为下载端,没有开放上传,并且只能从搜狐影音Peer和Flash Peer获取数据,不能从H5 Peer获取。无论哪种Peer,文件与Peer的信息映射都由Tracker来管理,Tracker由Proxy来代理调用。Proxy还管理了影音Peer的连接,而Flash Peer的连接则由Rtmfp Server来管理,因此这一步需要从Gateway获取到Proxy和Rtmfp Server,这样才能调用P2P系统的接口。
获取到Proxy和Rtmfp Server后,P2P Client将分别登录到这两个服务,并保持长连接,后续所有接口将通过这两个连接进行调用。如前面所述,请求Proxy是为了连接搜狐影音Peer,请求Rtmfp Server是为了连接Flash Peer。 登录Proxy的过程中会携带探测到的NAT类型,这样在请求某个文件的Peer时,Tracker将参考这个用户的NAT类型,按照指定的规则来匹配,这样将提高打洞成功率。 而登录Rtmfp Server时会将用户的candidates保存到Rtmfp-DB。
P2P Client请求HotVrs获取文件信息,主要输入参数为vid和清晰度,vid是一个剧的唯一标识,HotVrs返回的文件信息主要包含:
分段信息中包含了每个分段的HashId,以该HashId为索引,可以向Tracker请求缓存了该mp4分段的Peer。通过vid和mp4分段索引,可以向调度服务获取CDN的下载链接。这样,向P2P系统、CDN系统的请求参数都已经准备充分。
P2P Client请求Proxy获取缓存Peer的Peer,输入参数是文件HashId、请求的Peer个数、种类,Proxy将通过一致性哈希表到命中文件的Tracker上查找NAT类型、地域、运营商匹配的Peer并返回给客户端。
P2P Client使用了ICE协议进行打洞,需要先获取:
实际上ICE协议还有一种Relay Candidate,是用户的Relay服务(例如TURN)上的地址端口,主要用于双向的Relay交互,这里没有用到。
P2P Client要向某个搜狐影音Peer打洞,需要请求Proxy转发搜集到的Candidates,Proxy将该消息投递到目标的Proxy并下发给搜狐影音Peer,这个请求实际上就是让Peer启动打洞的请求;
与下载端一样,上传端Peer收到启动打洞的请求后,先创建一个udp socket绑定一个本地端口,并用这个socket请求STUN获取外网地址,搜集完Candidates后,在启动打洞请求的响应中返回自己的Candidates。
下载、上传端都获取到对方的Candidates后,开始向这些地址/端口发起探测,对方收到探测包,必须无条件返回响应,以先收到响应的地址为准,作为打通的通道的地址。 这里列举一下常见的NAT的类型:
理论上除了以下两种配对基本无法打通外,其他的配对完全可以打通:
因此Tracker在搜索Peer的过程中会过滤掉这样的NAT配对,但是在Peer极少的情况下,也可能返回这样的配对。这个时候由于对称型NAT的特点,可以尝试探测目标端口周围若干的端口,有比较小的几率能够打通。为了避免猜测的端口是同一时间的其他请求启动的,需要在探测包中携带一次请求会话的唯一标识,如果偶然打通了,返回的标识可以辨别是不是本次请求的响应。
Flash Peer直接调用librtmfp的连接接口,由librtmfp使用rtmfp协议完成打洞过程,其过程与搜狐影音的打洞过程比稍有不同。
经过以上步骤,P2P下载端和上传端打洞成功,建立了一条UDP的通道,就可以开始传输数据。
搜狐影音Peer以1KByte为一个传输单元,称为subpiece,这个主要考虑到UDP MTU。5分钟的mp4分段按照1KByte为单元进行编号,赋予一个id,每个请求携带subpiece id,搜狐影音Peer寻址到对应的数据,即可返回对应的数据。
理论上UDP的错包率极低,并且大部分操作系统默认开启了CRC校验,错包自动丢弃,但是为了保险起见,数据包中应包含数据的校验和,以保证数据的正确性。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/151124.html原文链接:https://javaforall.cn