Open axetroy opened 6 years ago
亲,有兴趣来我厂吗?
@XadillaX 肯定有呀,不过杭州对我太远了
你是哪的哇
@XadillaX 南宁,年后正要下海..哦不,下深圳:joy:
大神,我又来了,我刚刚才从github 拿到token,现在准备利用token登录,然后和你一样把博客内容写在issue里面,但是又有点问题,我该如何过滤不要显示别人发起的issue,只显示我自己发的 。。issue,,,好吧,我先fork你的blog看看什么源码
我有个疑问... C和B是怎么不通过中间服务器通信得... 只是通过ip和端口没法穿透到两个处于内网得服务器吧.. 举个例子,假设我是B位于天翼网关下面第二层路由下,创始节点能获取到我的公网ip也只是能得到天翼网关得地址,像网关请求显然我是不知道也不会有回应得呀?
@Tarhyru 一样的,内网穿透的原理都是这样,两个处在内网的服务器 B 和 C,一定需要一个中间服务器才能建立链接
B 和 C 都处在二层路由,但是天翼网关的一层路由的某个端口是映射到二级路由的,所以中间服务器只需要获取一级路由的 IP 和端口就行了。
@axetroy 那如果我想人为复现这个现象应该怎么作呢? 我发现,我在本地ping我得公网ip,有回应,直接连接80端口是天翼网关 但是,我在别的环境,比如阿里云上Ping这个公网ip没有回应...(但是 who 指令看到的ip和我pin的是同一个..)ping都Ping不通就更谈不上连接了... 所以,我只能内网通过SSH 反向代理到阿里云上,再在阿里云上通过正向代理将端口映射出去.. 其它环境正向连接阿里云映射的端口可以连接到我的本地... 然后,问题来了,这个连接会经过阿里云中转,也就是说连接速度受限于阿里云的带宽... 所以我想知道,有没有一种办法..像这个描述一样,通过中间节点建立连接,而不受限于中间节点得带宽?
@Tarhyru 中间节点仅仅是帮助两个处在内网的节点相互发现对方的存在,之后就没他什么事了,所以,不受限中间节点的带宽
@axetroy 好吧..这个道理我是明白了... 现在我想知道...怎么实现一个只帮助两个内网节点发现对方存在的中间节点...同时这两个相互发现的节点还能通信..... 昨天我telnet上天翼网关发现它就是一台linux服务器....连上发现外面还有一层....所以我从阿里云通过公网ip ping不到,但是telnet指令可以穿透..在网关上,Ping不通内网的机子..但是可以ping通公网的..内网的机子可以ping通网关... 现在我应该去查哪方面的内容..来实现我这个小需求?..我找内网穿透中间代理,一水的SSH.... 但是..通过SSH代理实现互相发现..明显是受限于代理的带宽... 我现在想的是..在网关上用iptables作转发....但是网关连接不到内层的路由或者机子..转发给谁..又是一个问题...
@Tarhyru
https://github.com/axetroy/p2p-chat/blob/a7153e0115597026c65a6760da38e48edd72fb29/router.js#L135
这是 UDP 协议的实现,只要是 socket 链接,都可以获取到它的 remoteAddress 和 remotePort
remoteAddress: 123.123.123.123 remotePort: 61231
remoteAddress: 321.321.321.321 remotePort: 41231
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的聊天应用,但是精力有限,就这样了。代码(写的丑,轻拍)
文字功底有点差,表述不清楚,见谅,如文中有误,欢迎指正与交流。