P2P打洞技术详解

2023-05-16

原文:https://rebootcat.com/2021/03/28/p2p_nat_traversal/

何为打洞?(what)

英文翻译

  • NAT traversal : NAT 穿越
  • NAT Hole Punching : NAT 打孔

定义

(UDP) 打洞技术是通过中间公网服务器的协助在通信双方的 NAT 网关上建立相关的映射表项,使得双方发送的报文能直接穿透对方的 NAT 网关(防火墙),实现 P2P 直连。

洞:所谓的洞就是映射规则,外部能够主动与之通信的规则

为何要打洞?(why)

直接连不行吗?

  • NAT 技术的存在,一方面减缓了 IPV4 的需求,使得私网 IP 地址通过映射成公网 IP 地址的方式与外界通信
  • 但另外一方面, NAT 也对安全性做了限制(防火墙),外界不能主动与私网 IP 进行通信

image-20210324201346047

打洞有什么好处?

  • 节省流量
  • 降低中心服务器压力
  • 下载速度快(比如迅雷、直播等)
  • 安全性和私密性

如何打洞?(how)

通常我们说的打洞技术基本上都是使用 UDP 来实现的,当然 TCP 也行,只不过会复杂一点(后面我们讨论一下 TCP 打洞)。

使用中继设备(proxy)

主要利⽤第三⽅的服务器作为中转服务器,⽐如Application Level Gateway (ALG),application server, application server with agent, TURN

有点是稳定可靠,缺点是延迟较⼤,不适合在p2p的⽹络中使⽤。

本质上其实不算 P2P 打洞的范畴了。

直连

基本思路是:A 和 B 互相知道对方的公网 IP:Port,使用对方公网 IP:Port 通信

通过修改通信协议,或者 NAT 设备来帮助节点之前的直接通信,⽐如: tunnel, NAT-PMP, UPnP, MidCom, STUN hole punching, ICE, Teredo等。 其中STUN hole punching⽅法在实践中应⽤最为 广泛。

  • UPnP: 把内网 IP 直接映射为 NAT 外网 IP (纯转发模式),类似公网 IP
  • STUN: 比较出名的打洞协议,本质上就是利用一台或多台公网服务器协助位于不同私网的两个节点 A 和 B 进行打洞。

NAT 设备类型

image-20210324201449678

  • Full Cone NAT: 允许任何外部 IP 任何端⼝连⼊ NAT,只要 NAT 内部 host 产⽣过 IP 端⼝映射。 (不限制任何 IP)

  • Restricted Cone NAT: 只允许外部指定 IP 连⼊当前 NAT,即 NAT 内 host 主动连 接过的 IP。(限制 IP)

  • Port-Restricted Cone NAT:只允许内⽹设备主动 连接过的外⽹ IP 和 Port 连⼊。(限制 IP + Port

  • Symmetric NAT:这种类型的 NAT ⾏为跟端⼝限制型的 NAT 类型相似,不同的是,对于向外连接的不同的 IP 和 Port,NAT 随机分配⼀个 Port 来完成地址转换,完成对外连接。(只要向外的 IP:Port 不一致则映射到不同端口

注意:对于前三种 NAT 设备,内网节点连接不同的 server {IP, Port} 对映射外网端口一致

主要有以上几种,市面上还有少量的其他类型

Full Cone NAT (全锥形)

  • NAT 映射规则形成后,外部其他主机能够主动与之通信

举例如下:

  1. A 位于私网内部
  2. A 访问 https://www.google.com/
  3. NAT-A 记录了映射规则,比如 {local_host,local_port,public_port,dest_host} 等信息
  4. 外部其他主机(比如 google.com) 能主动与 A 通信(通过 A 的 public_ip:public_port)

Restricted Cone NAT(限制型)

在 Full Cone NAT 的基础上多加了一条限制规则:

  • 只允许访问过的 server IP 与之通信

举例如下:还是上面的例子,后续只允许 https://www.google.com/ (对应 IP 203.107.53.50) 与之通信,而不 care 203.107.53.50 的端口号(比如从 6666 端口过来的数据)。

Port-Restricted Cone NAT(端口限制型)

在 Restricted Cone NAT 的基础上多加了一条限制规则:

  • 只允许访问过的 server {IP, Port} 与之通信

举例如下:还是上面的例子,后续只允许 https://www.google.com/ (对应 IP 203.107.53.50) 的 80 端口与之通信,其他端口不行

Symmetric NAT(对称型)

访问规则同 Port-Restricted Cone NAT:

  • 只允许访问过的 server {IP, Port} 与之通信

区别是连接不同的 server {IP, Port},映射到 NAT 上的公网 Port 不一致,且映射规则不确定

有些 NAT 设备会进行简单的 +1 操作实现端口映射,比如:{local_port: 6000, public_port: 6000, Server1},{local_port: 6000, public_port: 6001, Server2},{local_port: 6000, public_port: 6003, Server3}

有些 NAT 设备为了安全性,可能会随机进行端口映射,提高端口猜测的难度。

场景分析

(假设已经获取到⽬标邻居的IP Port 等信息)

  1. 先向公⽹服务器发起请求,探测⾃⼰是不是在⼀个 NAT 下
  2. 如果不在,说明自己是公网节点,可以与目标建立连接(让目标主动连接)
  3. 如果在,则获取⾃⼰的 NAT 类型是什么,根据不同的类型采取相应不同的策略

注意:A 和 B 均要与 server 一致保持连接心跳,确保 NAT 映射端口有效

节点 A 在 NAT 下面,节点 B 在公网环境中

打洞策略:

  • 只要保证节点 A 主动向节点 B 发起连接,两者就可以连接成功

image-20210324212632428

节点 A 和 B 在相同的 NAT 下

打洞策略:

  1. A 从 server 获取 B 的信息,server 同时发给 A 和 B 对方的信息(公网/私网信息)
  2. A 与 B 各自收到 server 的信息后,同时向对方发起连接,公网和私网都发(理论上私网会快一点),一旦收到回复,则停止
  3. 建立连接成功

image-20210324213025505

节点 A 和 B 在不同的 NAT 下(这是我们要重点讨论的)

节点 A 和 B 的 NAT 可能是任意一种 NAT 类型

  • A 和 B 均是锥形 NAT
  • A 和 B 分别是对称型和普通锥形(全锥形,限制型锥形)
  • A 和 B 分别是对称型和 Port-Restricted Cone NAT (端口限制型)
  • A 和 B 都是对称型

A 和 B 均是锥形 NAT

锥形 NAT 之间可以容易的打洞成功,具体流程如下:

image-20210324222800953

以下流程假定已经完成了 NAT 类型探测,A/B 知道自己的 NAT 类型,以及通过 NAT 映射出去的端口 PA1/PB1。

打洞策略:

  1. A 向 server 发起与 B 的打洞请求,server 向 B 转发打洞请求,同时A 向 PB1 直接发送探测包,那么 A 为 B 在 PA1 已经成功打洞,但是 A 的消息无法到达,因为 B 的 NAT 会将不明的地址(PA1) 丢弃。(注意:这里有可能不是丢弃,而是拒绝
  2. B 收到从 server 转发过来的打洞请求后,向 PA1 直接发送探测包,这时 B 的 NAT 可以放行 PA1 的消息了,也就是 B 为 A 在 PB1 上完成了打洞。
  3. 至此,A 和 B 消息能够互通,打洞成功

注意,上面斜体部分,NAT 对不明地址的行为可能是拒绝,待会会讨论。

A 和 B 分别是对称型和普通锥形(全锥形,限制型锥形)

假设 A 是对称 NAT,B 是普通锥形:

image-20210325095314524

打洞策略:

  1. A 向 server 发起与 B 的打洞请求,server 向 B 转发打洞请求,同时发送探测包到 PB1,这个探测包是从 PA2 发出的,不是 PA1(因为对称型)。也就是 A 在端口 PA2 为 PB1 完成打洞,同时 B 的 NAT 会丢弃来自不明地址 PA2 的包。(注意:这里有可能不是丢弃,而是拒绝
  2. B 收到从 server 转发过来的打洞请求,向 PA1 发送初始探测包(一开始不知道 PA2),这个时候 B 已经为 A 在 PB1 打好洞,至此 PA2 的消息能够通过 PB1 到达 B。(注意:因为是普通锥形,不对端口做限制,所以从不同端口 PA2 过来的包能被 B 接受
  3. 经过步骤2,B 可以收到 PA2 的消息,同时结合 A 的 NAT 类型,重新改发探测包到 PA2,于是 A 在 PA2 能收到 PB1 的探测包,至此 A 和 B 消息可以互通,打洞成功

如果 A 和 B 正好角色相反,那么可以调整打洞的方向即可

A 和 B 分别是对称型和 Port-Restricted Cone NAT (端口限制型)

原本大致过程是同上面一种场景,但是由于 B 是端口限制型 NAT,会导致 PB1 只允许 PA1 通过(上面红色字体部分B 已经为 A 在 PB1 打好洞),从而 PA2 过来的包会被 B 的 NAT 拒绝,导致打洞失败

A 和 B 都是对称型

由于 A 和 B 均是对称型 NAT,那么比上面一种场景更严格,A 和 B 探测得到的公网 Port 均会被修改,无法完成打洞

对称型打洞真的没有办法了吗?

我们再来考虑对称型和端口限制型的打洞,由于 B 收到 server 转发过来的打洞请求后,是向 PA1 发送探测包的,因为 B 只知道 PA1(PA1 是 A 与 server 连接是映射的端口号,server 也只知道 PA1),但是 A 由于是对称型 NAT,会从一个新端口 PA2 向 B 发包,但是 B 由于是端口限制型,只允许 PA1 端口的包通过,所以 B 会拒绝 PA2。

还是上面那张图:

image-20210325102706630

A 从 PA2 发向 B 的包一直会被 B 拒绝,也就是说 B 无法在 NAT-B 上为 A 打洞。

那***假如 B 探测包不是发往 PA1 而是 PA2 呢***?那 A 和 B 就能打洞成功。

那么问题来了,B 如何知道 PA2 呢?

通常来讲,有两种办法:

  • 端口探测
  • 端口预测

端口探测

对于对称型的 NAT在映射内网端口的时候,有一些 NAT 设备会采取比较傻瓜的端口分配方法,比如进行简单的线性变化

  • 比如每次分配的端口号递增 1
  • PA2 = (PA1 + PB1 + IPA + IPB) % 65535

对于这种 NAT,要探测这种特性需要用到两台及以上的公网 server,通过与不同的 server 连接映射的公网 Port,归纳总结自己的 NAT 映射规律,那么对于 B 来说,打洞的时候第一次向 A 发包,就直接往 PA2 发包就好了。

端口预测

有一些对称型 NAT 为了安全考虑,分配端口的方法难以预测,比如随机分配端口,那么对于这种情况,如何预测端口号呢?

  • 基于一个理论:生日攻击理论

生日攻击理论讲的是在一个班级里,每个人的生日可能是 365 天里的任何一天,每年有 365 天,如果要让 至少有两人的生日相同的概率超过 50%,问这个班级最少需要多少人?

答案是:(xx)

是不是出乎预料?

生日攻击理论说的直白点就是,利用了远小于样本集的尝试次数,就能够很大概率获得两个相同的碰撞采样结果。

那么针对端口号的样本集 65535,实际是 (1025, 65535],双方随机打洞需要尝试多少次(打多少洞)才能刚好碰撞成功呢?

>>> cat nat_birth_attack.py                                                                                                                                                                                         

#!/usr/bin/env python
#-*- coding:utf8 -*-


import os
import math
from decimal import *

getcontext().prec = 6

def birthday_attack(total, rate):
    k = 0
    while True:
        k += 1
        a,t = 1,1
        for i in range(k):
            a = a * (total - i)
            t = t *  total

        np = Decimal(a) / Decimal(t)
        p = 1 - np
        if p > rate:
            print('total:{0} trytimes:{1}  result:{2} > target_rate:{3} success'.format(total, k, p, rate))
            break
        else:
            print('total:{0} trytimes:{1}  result:{2} < target_rate:{3} failed, continue...'.format(total, k, p, rate))
            continue

    return k



if __name__ == '__main__':
    total_samples = 365
    rate = 0.5
    min_k =  birthday_attack(total_samples, rate)
    print("when total_samples is {0}, if request for rate greater than {1}, then try at least {2} times is ok\n".format(total_samples, rate, min_k))

运行结果:

>>> python nat_birth_attack.py                                                                                                                                                                                      ‹git:master ✘› 11:00.53 四  3 25 2021 >>>
total:365 trytimes:1  result:0 < target_rate:0.5 failed, continue...
total:365 trytimes:2  result:0.002740 < target_rate:0.5 failed, continue...
total:365 trytimes:3  result:0.008204 < target_rate:0.5 failed, continue...
total:365 trytimes:4  result:0.016356 < target_rate:0.5 failed, continue...
total:365 trytimes:5  result:0.027136 < target_rate:0.5 failed, continue...
total:365 trytimes:6  result:0.040462 < target_rate:0.5 failed, continue...
total:365 trytimes:7  result:0.056236 < target_rate:0.5 failed, continue...
total:365 trytimes:8  result:0.074335 < target_rate:0.5 failed, continue...
total:365 trytimes:9  result:0.094624 < target_rate:0.5 failed, continue...
total:365 trytimes:10  result:0.116948 < target_rate:0.5 failed, continue...
total:365 trytimes:11  result:0.141141 < target_rate:0.5 failed, continue...
total:365 trytimes:12  result:0.167025 < target_rate:0.5 failed, continue...
total:365 trytimes:13  result:0.194410 < target_rate:0.5 failed, continue...
total:365 trytimes:14  result:0.223103 < target_rate:0.5 failed, continue...
total:365 trytimes:15  result:0.252901 < target_rate:0.5 failed, continue...
total:365 trytimes:16  result:0.283604 < target_rate:0.5 failed, continue...
total:365 trytimes:17  result:0.315008 < target_rate:0.5 failed, continue...
total:365 trytimes:18  result:0.346911 < target_rate:0.5 failed, continue...
total:365 trytimes:19  result:0.379119 < target_rate:0.5 failed, continue...
total:365 trytimes:20  result:0.411438 < target_rate:0.5 failed, continue...
total:365 trytimes:21  result:0.443688 < target_rate:0.5 failed, continue...
total:365 trytimes:22  result:0.475695 < target_rate:0.5 failed, continue...
total:365 trytimes:23  result:0.507297 > target_rate:0.5 success
when total_samples is 365, if request for rate greater than 0.5, then try at least 23 times is ok

把 total 修改成 65535,概率 rate 修改成 80%,计算得到尝试次数为 460 次。

total:65536 trytimes:460  result:0.801039 > target_rate:0.8 success
when total_samples is 65536, if request for rate greater than 0.8, then try at least 460 times is ok

也就是说对于 B 来说,可以尝试随机往 A 的 460 个不同的端口发探测包,就有 80% 的概率能够正好预测到 NAT-A 随机分配的 PA2。

460 个探测包的代价基本可以忽略不计。

image-20210325113426160

至此,可以完美实现对称型和端口限制型的打洞。然而遗憾的是,对于对称型和对称型打洞,依然无法实现。

再来讨论下 NAT 对陌生地址包的行为

上面能够打洞成功的场景下,都是基于一个前提是 NAT 对陌生地址发来的包采用的是丢弃策略。这里的陌生地址指的是自己没有主动往外发包的 {dest_ip, dest_port} 对。

如果不是丢弃,而是采用黑名单机制呢?为了安全考虑,有一些 NAT 在收到陌生地址的包后,会触发防火墙模块,并且在自己的 deny 列表中增加一项{PA2, PB1},随后自己再往 A 发包的时候,本来打算使用 PB1 进行发包,但是发现 deny 列表里已经存在了 PB1,于是会重新选择一个端口号 PB2 发包。于是对于这种锥形 NAT 会退化成对称型的 NAT。

知道了这个原理,要解决也很容易。

  • 设置有限 TTL,避免惊动对方防火墙
  1. 一开始 A 往 B 发包,可以设置 TTL 为 3,这个数大到足够通过自己的外网 NAT(可能有多层),又会被中间的某个运营商 router 丢弃,从而不会惊动 B 的防火墙模块,同时为 B 打好了洞。

  2. 同理,B 也做类似的操作,为 A 打好洞

  3. A 和 B 两边都等待一段时间,比如 2 s

  4. 再互相发探测包,不用设置 TTL

  5. 打洞成功

关于 TTL 的值设置为多少,需要做一定的探测,不然可能设置过小,也许都没有走出自己的 NAT,设置过大,可能导致惊动了对方的防火墙

总结一下

NAT全锥形限制型锥形端口限制型锥形对称型
全锥形DirectDirectDirectDirect
限制型锥形DirectHole PunchHole PunchHole Punch
端口限制型锥形DirectHole PunchHole PunchHole Punch
对称型DirectHole PunchHole PunchRelay

扩展:讨论一下 TCP 打洞的可行性

TCP 也能实现 NAT 打洞,只不过相比 UDP 会更复杂一点。原因是:

  • 一个UDP套接字由一个二元组来标识,该二元组包含一个目的地址和一个目的端口号;而一个TCP套接字是由一个四元组来标识,包括源IP地址、源端口号、目的IP地址、目的端口号
  • TCP 套接字仅允许建立 1 对 1 的响应,即应用程序将一个套接字绑定到本地的端口后,试图将第二个套接字绑定到该端口的操作都会失败

基本打洞策略如下:

  1. A 和 B 分别位于不同的 NAT 下面
  2. A 启动 tcp client,bind 一个 local_port PA1’,执行 connect 连接公网 tcp server,server 获取 A 的映射公网端口 PA
  3. B 同上,B 启动 tcp client,bind 一个 local_port PB1’,执行 connect 连接公网 tcp server,server 获取 B 的映射公网端口 PB
  4. A 和 B 保持和 server 的连接,不断开,避免各自的 NAT 上的映射规则过期 {PA1’ -> PA} 和 {PB1’ -> PB1}
  5. A 和 B 通过 server 互相获取对方的公网 Port PA1 和 PB1,准备开始打洞
  6. A 新启动一个 tcp 套接字,使用 SO_REUSEADDR/SO_REUSEPORT 绑定到之前与 server 连接的本地端口,也就是 PA1’,并且调用 listen 处于等待监听状态
  7. B 同上,bind PB1’ 并且调用 listen 处于监听状态
  8. A 再新建一个套接字 bind 到之前的端口,调用 connect 发起向 PB1 的连接,也就是 A 往 PB1 发送 syn 包,也就是为 B 打洞,NAT-B 会丢弃这个包
  9. 同时 B也再新建一个套接字 bind 到之前的端口, 也调用 connect 发起向 PA1 的连接,也就是 B 往 PA1 发送 syn 包,也就是为 A 打洞
  10. 假设 A 发送完 syn 之后,B 的 syn 包达到了 NAT-A,NAT-A 能通过,这个时候有的 linux 系统上 A 会认为自己的异步 connect 调用成功,同时利用相同的 seq 发送 SYN+ACK 包 到 PB1,NAT-B 也能顺利通过,再返回 ACK 包,连接建立成功;有的 linux 系统会走正常的 accept 操作,也能顺利建立连接

扩展:讨论一下打洞的有效时间

在 NAT 上的映射规则有失效时间,如果要保持洞口的有效性,需要保持打洞双方的心跳。比如在手机上,这个洞口可能会在 1 min 后失效

扩展:讨论一下多层 NAT 的打洞

我感觉其实单层 NAT 应该是类似的。

Blog:

  • rebootcat.com

  • email: linuxcode2niki@gmail.com

2021-03-28 于杭州
By 史矛革

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

P2P打洞技术详解 的相关文章

  • word将一个文档的样式导入到另一个文档

    一 背景 在word中编辑文档时 经常需要定义一个样式给特定格式的文本使用 如标题1 标题2等 而有时需要在一个新文档A中使用一个旧文档B中定义好的样式 二 操作步骤 1 打开旧文档B 选择上方标签栏的 样式 gt 管理样式 如图 2 在弹
  • 解决在cmd情况下无法连接MySQL情况(无脑操作教程)

    在输入外部命令 mysql u root p的时候 出现下面的情况 网图 侵删 问题分析 可能是MySQL路径问题没有解决 解决方法 1 打开电脑高级设置 2 点击环境变量 3 找到path路径变量后 点击编辑 4 新建路径 此路径是我保存
  • SEGGER_RTT_printf()函数实现打印浮点、负数-示例

    概述 最近公司项目换另一款gsensor 用到了浮点数打印 又不想使用串口来打印数据 在此做个笔录 通过修改源码方式实现 一 修改源码 1 在 SEGGER RTT printf c 中 的 int SEGGER RTT vprintf u
  • centOS 安装 elasticsearch 7.0.0和kibana7.0.0_单机版

    cd opt wget wget https artifacts elastic co downloads elasticsearch elasticsearch 7 0 0 linux x86 64 tar gz tar xzvf ela
  • CAN分析仪 USBCAN USB转CAN CAN转换调试器接口卡使用指导

    USBCAN系列便携式CAN分析仪 通过USB接口快速扩展一路CAN通道 使接入CAN网络非常容易 它具有一体式和小巧紧凑的外形 特别适合于随身携带 第一步 将usbcan卡连接电脑如图 usb灯亮红灯 打开 USBCAN系列便携式CAN总
  • PLC控制电动机的顺序启动逆序停止

    一 PLC控制电动机延迟启动正转和反转 实验要求 当按下电动机的正转启动按钮时 电动机需要延迟30秒后 电动机才会正转启动工作 当按下反转按钮时 电动机需要延迟20秒后 电动机才会反转启动工作 当按下停止按钮时电动机立刻停止工作 PLC I
  • 手把手教你通过端口映射,轻松搭建Windows远程桌面

    市面上有很多的远程桌面软件 如TeamViewer 向日葵等 但无一例外 它们提供的免费服务连接质量普遍不高 而付费服务价格又偏高 并不能使人满意 但众所周知 微软自带的Windows远程桌面其实在连接质量和稳定性方面一点都不输给第三方软件
  • IP包头&ARP协议笔记

    一 IP包头分析 1 帧中的IP包头 从版本到可选项 其中2为帧头 注 1 IP包头最小长度 20字节 即可选项以前部分 IP包头长度是可变的 2 可选项最长可以是40个字节 故IP包头最长可以是60个字节 1 版本 4 说明是IPv4 2
  • Windows实例如何通过本地安全策略限制远程登录的IP地址

    Windows实例如何通过本地安全策略限制远程登录的IP地址 阿里云 禁止所有的IP地址连接服务器的RDP端口 远程连接登录服务器 单击 开始 选择 运行 输入gpedit msc 单击 确定 打开本地组策略编辑器 在左侧依次找到 计算机配
  • Android 可以进行点对点自组织网络吗?

    是否可以将 Android 设置为 ad hoc 对等 wifi 模式 例如 我想让一部电话广播一条消息 并让网络中的所有对等方接收广播 而无需服务器 我想使用 wifi 因为蓝牙范围更有限 这是有关您请求的功能的错误报告 它的状态是 已审
  • 是否可以连接两个或多个 WiFi Direct 组?

    我目前正在为我正在进行的一个项目尝试 WiFi Direct WiFiP2p 并想知道是否可以在组之间创建桥梁 从而将它们连接在一起 基于白皮书由 WiFi 联盟发布 这应该是可能的 尽管 P2P 规范没有描述此功能的机制 实施是特定于供应
  • 实现 p2p 消息广播网络的最新技术是什么?

    我知道快速谷歌可以得到大量的结果 并且关于这个主题的文献非常丰富 而这正是问题所在 在众多可能的解决方案中 我不确定哪一个是满足我的特定需求的最佳 最新的选择 我正在尝试在互联网上实现一个 p2p 网络 其唯一的功能是将消息广播到在线节点
  • UDP打洞帮助

    我正在尝试使用点对点将互联网网络添加到我的游戏中 我已经实现了仅 LAN 版本 它使用 NET 的对等类在本地网络内进行连接 我意识到我需要使用 UDP 打洞来建立与防火墙后面的其他客户端的连接 这就是我开始实施它的方式 该服务器是一个 H
  • Windows Metro 应用程序中没有 P2P?

    在 BUILD 的 NET 开发人员对 Windows 8 应用程序开发的看法 会议中 讲师提到 Metro 配置文件中仅公开了客户端 WCF 功能 我们无法创建服务器 http channel9 msdn com Events BUILD
  • 如何以最小的开销实现简单的无服务器 p2p 浏览器到浏览器消息传递?

    我正在尝试创建一些简单游戏的基本实现 井字游戏是起始项目 这些游戏可以通过互联网玩 而不需要中央服务器 该页面甚至不需要托管 可以在计算机上本地运行 也可以托管在 Web 服务器上 托管游戏时 页面会通知主机他的 IP 地址 然后可以通过任
  • 如何在两个设备(android,iphone)之间传输“数据”?

    如何在两个设备之间传输数据 我想在不同平台 android iphone 之间传输数据 主要是图像文件 是否可以使用 p2p 或者我应该使用客户端服务器 任何帮助将不胜感激 你看过吗高通的 AllJoyn 库 https developer
  • 如何通过peerJS 点对点连接接收数据?

    我正在尝试使用peerJS 连接两个对等点 我几乎只是在遵循他们的 入门 但我仍然在挣扎 下面是我到目前为止得到的代码
  • 使用中间服务器创建点对点连接

    我想连接两个客户端 通过 TCP IP 套接字 客户端可以使用中间服务器发现彼此 一旦客户端发现彼此 服务器就不应该有任何参与 我对此做了一些研究 发现很多人建议JXTA 但我想自己从头开始创建协议 因为将来我可能也必须使用 WebSock
  • 向Kademlia添加新节点,构建Kademlia路由表

    我无法完全理解 Kademlia DHT 的加入过程 我在网上看过一些教程和演示文稿 但它们似乎都以相同的方式说事 并且所有伪代码等在大多数情况下都是相同的 实际复制 粘贴 有人可以对此进行高水平的演练吗 我假设您已经阅读过木兰纸 http
  • 为什么WebRTC需要ICE协议才能运行?

    据我了解 ICE协议用于发现从最终用户设备到 外部 的节点 设备 我不明白为什么需要它 数据包路由不是由路由器和交换机等网络设备负责吗 他们应该找到从网关到最终用户设备的最短路径 实际上 路由器会记住他们之前发现的那些路由 此外 NAT 协

随机推荐