V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dbfox
V2EX  ›  程序员

分别在不同地区的两台计算机(北京某网吧某计算机 A,上海某网吧某计算机 B),通过 UDP 打洞之后,可以不经过服务器进行文件传输、视频聊天、文字聊天么?

  •  
  •   dbfox · 2016-04-29 17:20:44 +08:00 · 6864 次点击
    这是一个创建于 3133 天前的主题,其中的信息可能已经有所发展或是发生改变。
    P2P 打洞有接触过的么?实现思路是什么?
    网上看了一堆博文,试验过几个例子,都以失败告终
    QQ 是怎么实现的?


    个人理解:

    北京某网吧某计算机 A ,上海某网吧某计算机 B

    A 如果 要与 B 进行通讯,需要借助服务器 S

    A 与 服务器 S 建立连接
    B 与 服务器 S 建立连接


    A 想发信息给 B ,首先是 A 把信息 发送给 S , S 再发给 B ,但是这样不叫 P2P ,而且服务器 S 在用户多的情况下流量是个问题。

    我想实现 A 在 S 的帮助下与 B 可以直接通讯, B 也可以直接通讯 A

    A 连接上 S , B 连接上 S , S 通过什么手段 可以让 A 与 B 直接通讯呢?
    35 条回复    2016-05-01 14:43:48 +08:00
    morven
        1
    morven  
       2016-04-29 17:27:29 +08:00 via iPhone
    直接通讯的话公网 IP 或 dzm 是必要的吧
    colatin
        2
    colatin  
       2016-04-29 17:28:32 +08:00
    如果是严格的 NAT ,肯定无法直接通信。
    dbfox
        3
    dbfox  
    OP
       2016-04-29 17:31:41 +08:00
    看到了这里我大致也理解了

    双方都在局域网内就没有办法 TCP 直连了,所以像 QQ 等都会尽量使用 UDP 直连的

    IP 地址转换不需要你处理,网关默认就已经进行了转换。
    服务器接收到 DatagramPacket 中 getAddress 和 getPort 已经是网关的端口


    UDP 打洞的过程大致如此:
    1 、双方都通过 UDP 与服务器通讯后,网关默认就是做了一个外网 IP 和端口号 与你内网 IP 与端口号的映射,这个无需设置的,服务器也不需要知道客户的真正内网 IP
    2 、用户 A 先通过服务器知道用户 B 的外网地址与端口
    3 、用户 A 向用户 B 的外网地址与端口发送消息,
    4 、在这一次发送中,用户 B 的网关会拒收这条消息,因为它的映射中并没有这条规则。
    5 、但是用户 A 的网关就会增加了一条允许规则,允许接收从 B 发送过来的消息
    6 、服务器要求用户 B 发送一个消息到用户 A 的外网 IP 与端口号
    7 、用户 B 发送一条消息,这时用户 A 就可以接收到 B 的消息,而且网关 B 也增加了允许规则
    8 、之后,由于网关 A 与网关 B 都增加了允许规则,所以 A 与 B 都可以向对方的外网 IP 和端口号发送消息
    tinyproxy
        4
    tinyproxy  
       2016-04-29 17:32:15 +08:00   ❤️ 1
    1. DHT 协议收好 http://www.bittorrent.org/beps/bep_0005.html
    2. P2P 启动的时候需要一个 Bootstrap 服务器,介绍你入党并告诉你几个其他党员的存在,然后你跟其他党员愉快的搅基的时候就可以不用管入党介绍人了。
    3. 说错了请楼下轻拍, P2P 的东西只研究过 DHT 。
    dbfox
        5
    dbfox  
    OP
       2016-04-29 17:38:54 +08:00
    @tinyproxy 感谢 5/1 研究研究
    lbp0200
        6
    lbp0200  
       2016-04-29 19:25:02 +08:00 via Android
    有个开源项目,狗洞
    zhicheng
        7
    zhicheng  
       2016-04-29 19:34:31 +08:00 via Android
    不是所有的 NAT 都能打洞。
    laiyingdong
        8
    laiyingdong  
       2016-04-29 19:40:42 +08:00
    有一个应用实现 N2N VPN 与 QQ 等等 UDP 打洞是类似的 需要注意的是如果是 Symmetric (对称) NAT 穿透是很困难的 (网吧不可能 因为要玩游戏必须要 UDP 穿透)
    SlipStupig
        9
    SlipStupig  
       2016-04-29 20:26:52 +08:00
    用 stun 可以实现你想要的....
    qile1
        10
    qile1  
       2016-04-29 20:38:15 +08:00 via Android
    具体打洞不太清楚,我认为数据传输可能需要两个内网通过互通后可以实现
    jimzhong
        11
    jimzhong  
       2016-04-29 20:54:09 +08:00
    如果双方 NAT 设备靠谱,应该是可以实现的。
    iwege
        12
    iwege  
       2016-04-29 22:02:07 +08:00
    打洞的不知道
    后面的可以考虑走 webrtc
    ahtsiu
        13
    ahtsiu  
       2016-04-30 00:25:54 +08:00
    stun , voip 的最佳拍档
    msg7086
        14
    msg7086  
       2016-04-30 03:16:35 +08:00
    @tinyproxy DHT 是个 Hashtable 。
    jsq2627
        15
    jsq2627  
       2016-04-30 03:34:42 +08:00 via iPhone
    stun 打洞
    turn 中转
    ice 全自动协商
    tinyproxy
        16
    tinyproxy  
       2016-04-30 08:10:05 +08:00 via iPhone
    @msg7086 是,但楼主要的东西,模仿 dht 做一套是能搞定的,至于你说的 hash table ,既然自己做了,这个函数自己改改就好了,或者扩充一下协议也行。
    msg7086
        17
    msg7086  
       2016-04-30 08:43:15 +08:00
    @tinyproxy 楼主并不需要哈希表。
    msg7086
        18
    msg7086  
       2016-04-30 08:44:23 +08:00
    @tinyproxy 我仔细想了想你的回复,觉得你应该是没有审题。
    haoc
        19
    haoc  
       2016-04-30 09:09:48 +08:00
    需要例子的话,试一下 webrtc 呀~~
    aru
        20
    aru  
       2016-04-30 09:55:31 +08:00
    sjqlwy
        21
    sjqlwy  
       2016-04-30 10:38:21 +08:00
    蒲公英路由器,哈哈😄
    cchange
        22
    cchange  
       2016-04-30 11:26:50 +08:00
    大家有什么比较好的内网互通软件吗?

    我希望可以用 VNC 来代替 teamviewer 虽然 teamviewer 非常非常好用
    hzqim
        23
    hzqim  
       2016-04-30 12:11:57 +08:00
    几年前, VeryCD 出过内网版电驴,不知道是否符合楼主所说
    lefthand2006
        24
    lefthand2006  
       2016-04-30 12:44:06 +08:00
    n2n 可以实现楼主需求,变广域网电脑成虚拟内网,但现在的 supernode 都不稳定,可能需要自架一个
    tinyproxy
        25
    tinyproxy  
       2016-04-30 20:07:37 +08:00 via iPhone
    @msg7086 他要一个 P2P 的通信软件,我的建议是模仿 DHT 做一套,有啥问题?开始两个节点都不知道对方的存在,通过 bootstrap 服务器开始搜寻其他节点啊,能发现其他节点了,那该传输啥还不是你想怎么写怎么写,为啥纠结哈希表?
    SearchDream
        26
    SearchDream  
       2016-04-30 20:46:36 +08:00 via iPhone
    你的理解是对的, verycd 的 emule 里有实现,你可以参考一下。
    xiamx
        27
    xiamx  
       2016-04-30 23:38:22 +08:00
    @tinyproxy 因为本来就不需要 distributed hash 阿, OP 没有要求分布式。整个项目也可以不通过 DHT 实现, DHT 只是没来由的增加了项目的复杂度
    @msg7086
    tinyproxy
        28
    tinyproxy  
       2016-05-01 01:09:24 +08:00
    @xiamx 我怀疑你完全没看懂我的回复。我拿楼主的话贴着评论好了。


    我想实现 A 在 S 的帮助下与 B 可以直接通讯, B 也可以直接通讯 A
    > 我的回复的里, bootstrap 服务器对应的就是 S, A,B 发送类似 DHT 的 find_nodes 给 S ,这样就可以获取到对方的网络地址了,剩下其他的通信模块,肯定得自己写,现有的 DHT 网络肯定是没有办法复用的。
    > 至于你说的可以不通过 DHT 实现,我完全赞同,我只是说我自己的思路,参照 DHT 自己设计协议有什么问题?不过你要说增加复杂度,请问你的思路是什么样子的?不给参照就给我下结论不合适吧。
    > 最后,别跟我扯 hashtable 了,我一开始说的就是自行设计协议,不然你我完全不在一个频道交流没有任何意义。
    xiamx
        29
    xiamx  
       2016-05-01 02:00:17 +08:00
    真令人无语啊
    QQ, skype, etc 在不使用分布式信息存储的情况下依然实现了使用 UDP 打洞的 P2P 通讯。 OP 问的是 UDP 打洞的实现,不是 DHT/Kadmelia/chord 这类东西...

    @tinyproxy
    msg7086
        30
    msg7086  
       2016-05-01 02:22:46 +08:00
    @tinyproxy 说真的,多花 1 分钟时间重新阅读一下 OP 的问题,很难吗?

    如果真的很难,那我帮你总结一下 TL;DR 吧。

    1. P2P 打洞有接触过的么

    OP 的提问是关于 P2P 里打洞的技术,不是 P2P 里节点发现的技术。

    2. QQ 是怎么实现的?

    QQ 之间互相传送文件时,两个节点是互相知道对方的。 QQ 上互相发送信息,腾讯服务器必然有维护通讯链接,返回对方的 IP 地址根本不需要查分布式表, QQ 用户也不需要维护分布式节点表。 OP 问的是两个 QQ 用户在传送文件时如何通过 NAT 打洞来完成直接发送而不是服务器中转流量。

    3. A 连接上 S , B 连接上 S , S 通过什么手段 可以让 A 与 B 直接通讯呢?

    OP 最后的总结很明显的写了需求。 OP 从来没说过要做一个群 P 的通讯软件, OP 要做的是一个让两个不同内网的客户端能够互发数据的通讯软件。

    4. 你我完全不在一个频道交流没有任何意义。

    是的。回答问题首先要审题。 3 楼 dbfox 自己的回答其实已经是很标准的答案了。
    如果你的回答是在一个问如何制作匿名 P2P 通讯软件的帖子里,那是很有用的回答, EM 的 KAD 和 BT 的 DHT ,现今著名的两大无服务器节点发现哈希网络。
    但是回答的仍然不够准确,因为 DHT ·就·是·哈希表(而不是你所说的「别跟我扯 hashtable 」)。
    BT 里的 DHT 是用来做 种子 Hash->[节点] 的列表映射的,也就是说 DHT 维护的并不是其他节点的列表,而是种子到节点的映射。你必须要有一个键,才能在 DHT 这个哈希表里找到这个键对应的节点列表。因此只能用在 多 P2P 的情况下,比如 BT 或者 EM 这样多人下载一个文件的场景下。两个人做 1P 2 1P 的单点传送, DHT 没有什么价值。
    以及你一开始说的 Bootstrap 和 DHT 没什么关系。如果 A 和 B 互相不知道对方,只需要 Bootstrap 就行了,一丁点也不会用到 DHT 。

    希望这篇阅读理解的分析能让你理解 OP 到底是在问什么。
    msg7086
        31
    msg7086  
       2016-05-01 02:26:40 +08:00
    @tinyproxy 建议你再花点时间去搞清楚 DHT 也就是 Distribute Hash Table 到底是用来干什么的再来争吧。
    看你的回复真的是醉得不行了。

    @xiamx 233 我是醉了
    xiamx
        32
    xiamx  
       2016-05-01 02:48:19 +08:00
    @msg7086 XD XD 你居然写了这么多,看来周末也是很闲的么
    msg7086
        33
    msg7086  
       2016-05-01 04:11:12 +08:00
    @xiamx 吃饱了没事做于是就上来随便说些有的没的
    wym0823
        34
    wym0823  
       2016-05-01 09:20:24 +08:00
    tox ,你值得拥有, https://github.com/irungentoo/toxcore
    nekocode
        35
    nekocode  
       2016-05-01 14:43:48 +08:00
    @msg7086 喜闻乐见大力打脸 23333
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5512 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 09:00 · PVG 17:00 · LAX 01:00 · JFK 04:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.