分别在不同地区的两台计算机(北京某网吧某计算机 A,上海某网吧某计算机 B),通过 UDP 打洞之后,可以不经过服务器进行文件传输、视频聊天、文字聊天么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
dbfox
V2EX    程序员

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

  •  
  •   dbfox 2016-04-29 17:20:44 +08:00 7283 次点击
    这是一个创建于 3513 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 吃饱了没事做于是就上来随便说些有的没的
    vip1024
        34
    vip1024  
       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     Solana     2940 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 43ms UTC 13:31 PVG 21:31 LAX 05:31 JFK 08:31
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86