-
-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
搭建P2P网络的原理 #166
Comments
亲,有兴趣来我厂吗? |
@XadillaX |
你是哪的哇 |
@XadillaX |
大神,我又来了,我刚刚才从github 拿到token,现在准备利用token登录,然后和你一样把博客内容写在issue里面,但是又有点问题,我该如何过滤不要显示别人发起的issue,只显示我自己发的 。。issue,,,好吧,我先fork你的blog看看什么源码 |
我有个疑问... |
@Tarhyru B 和 C 都处在二层路由,但是天翼网关的一层路由的某个端口是映射到二级路由的,所以中间服务器只需要获取一级路由的 IP 和端口就行了。 |
@axetroy |
@Tarhyru |
@axetroy |
@Tarhyru https://github.com/axetroy/p2p-chat/blob/a7153e0115597026c65a6760da38e48edd72fb29/router.js#L135 这是 UDP 协议的实现,只要是 socket 链接,都可以获取到它的 remoteAddress 和 remotePort A 机器:remoteAddress: 123.123.123.123 B 机器:remoteAddress: 321.321.321.321 过程A --> 中间节点 (此时中间节点知道了 A 机器的 remoteAddress 和 remotePort, 并且给它起个名字叫做 A) B --> 中间节点 (此时中间节点知道了 B 机器的 remoteAddress 和 remotePort, 此时 B 机器并不知道 A 机器的存在) B (我要连接A机器)--> 中间节点 B <--(这是它的IP: 123.123.123.123, 端口: 61231, 你们自己玩去,别烦我) 中间节点 B --> A |
这么高级的..研究研究.. |
直接用 WebRTC 应该会好搞一些,使用 STUN 来穿墙,不行就使用 TURN 中继。服务端有开源的 Kurent 和 Licode。 |
流弊 |
@XadillaX 哪个厂啊?我有兴趣 |
最近在研究P2P技术,奈何相关资料不多,自己琢磨了一下,分享一下学习P2P的一些原理, 以及如何打造一个P2P聊天应用。
这里指的P2P是指peer to peer, 点对点的技术, 每个客户端都是服务端,没有中心服务器,不是websocket针对某个connection推送消息。
技术要点
原理
首先解决的是内网穿透的问题,常见的底层协议tcp,udp,他们各自有优缺点,简单说明一下。
tcp:需要处理粘包问题,双工流通道,是可靠的链接。
udp: 每次发送的都是数据包,没有粘包问题,但是连接不可靠,只能传输少量数据
更加详细的请Google
这里选择udp协议,简单一些。
再下来是内网穿透,先说结论: 两个处于不同内部网络的节点,永远无法发现他们之间的相互存在,你就算是想顺着网线过去打他都不行。
所有的内网穿透原理无外乎需要一个有公网ip的中介服务器,包括虚拟货币像比特币之类的,所以首先要有一个创世节点
在NodeJS中,创建udp服务也很简单
把服务部署要公网,那么其他所有的节点都能访问,通过中转服务器,能够使得两个节点可以建立连接
我们是要建立这样的P2P网络
假如现在只有3个节点: 创世节点, B节点, C节点, 创世节点有公网IP
我用对话的形式,阐述他们建立链接的过程:
...
至此,所有人都知道了B节点加入了网络,里面记载着B节点的相关信息,包括IP地址,包括udp端口号
此时C节点也要加入网络,并且想要和B节点对话:
到这里,B获取到了C的信息,包括IP和端口,C也拿到了B的信息.
于是,他们两个就可以建立通信。消息流: B <----> C. 中间不经过任何服务器
用一张图来形容:
总结
在设计中,每个节点的功能都是一样的。如果需要加入到网络中,不一定跟创世节点链接
假设已存在的节点: 创世节点,A、B、C节点,此时有个D节点想要加入到网络。
那么D节点不一定非得链接到创世节点,可以链接到A、B、C中的任意一个节点,然后该节点再广播给其他节点说"Hey, 有个新人叫做D的加入了网络"。
这样所有人都知道,有个叫做D的节点存在,你可以和它通信,同时D节点和会同步已存在的节点。这样D节点也知道了其他节点的存在了。
最后
基于这一原理,可以打造出一个P2P的聊天应用,没有中间商赚差价。
这只是一些基本原理,离实际应用还差很多,有很多坑,比如D节点退出网络之后,要广播 “D节点退出网络了,把这个节点注销了吧,这波没他",还有消息加密,通信的双向验证(A节点想要B节点通信,但是不需要B节点的同意)等等,坑太多,填不完
原计划是搭建这么一个网络,然后写个electron的聊天应用,但是精力有限,就这样了。代码(写的丑,轻拍)
文字功底有点差,表述不清楚,见谅,如文中有误,欢迎指正与交流。
The text was updated successfully, but these errors were encountered: