当互联网不可用:几种实用的替代通信方案

2026-05-15 42 预计阅读时间:1 分钟
来源:ruanyifeng.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:12 分钟

互联网不是永远在线的。自然灾害断网、偏远地区无信号、审查封锁——这些场景下,传统即时通信工具全部失效。但数据交换的需求不会消失。近几年,围绕"去中心化""离线优先""mesh 网络"的替代通信方案逐渐成熟,有些已经可以直接上手部署。

传统通信的隐含前提

微信、Telegram、Slack 这类工具都依赖同一个前提:两端能访问同一台中心服务器。断网的那一刻,这个前提就不成立了。即便端到端加密保证了内容安全,连接本身仍然依赖基础设施。

真正需要关注的是两类问题:

  • 连接层:没有 IP 网络,设备之间如何发现彼此、建立链路?
  • 应用层:消息如何存储、转发、确认送达,而不依赖中心数据库?

下面几个方案从不同角度回答了这些问题。

LoRa Mesh:Meshtastic 的低功耗长距离通信

Meshtastic 是目前最活跃的 LoRa mesh 项目。每台设备是一个节点,自动与附近节点组网,消息沿 mesh 逐跳转发。典型场景:户外徒步团队每人携带一个 LoRa 模块,即使完全没有手机信号,群内消息仍然可达。

硬件成本很低——一个 ESP32 + LoRa 模块大约 50 元人民币。通信距离市区约 300 米,开阔地可达 5–10 公里。功耗极低,一节 18650 电池能跑数天。

# 安装 Meshtastic CLI(Python 包)
pip install meshtastic

# 查看已连接设备的当前配置
meshtastic --info

# 发送一条文本消息到默认频道
meshtastic --sendtext "所有人集合,坐标 N39.9 E116.3"

# 设置节点名称,方便 mesh 内识别
meshtastic --set-owner "救援A组-01"

# 查看 mesh 内可见的其他节点
meshtastic --nodes

Meshtastic 也提供 Python SDK,可以嵌入到自定义应用中:

import meshtastic
import meshtastic.tcp_interface

# 通过 TCP 连接到本地 Meshtastic 设备(设备先通过 USB 或 WiFi 连到主机)
interface = meshtastic.tcp_interface.TCPInterface(hostname="localhost")

# 发送消息
interface.sendText("传感器读数: 温度22°C 湿度65%", channelIndex=0)

# 获取节点列表
nodes = interface.nodes
for node_id, node_info in nodes.items():
    print(f"节点: {node_info.get('user', {}).get('longName', '未知')}  "
          f"SNR: {node_info.get('snr', 'N/A')}  "
          f"距离: 约 {node_info.get('distance', '未知')}m")

interface.close()

注意:LoRa 通信速率极低(约 250 bit/s),只适合短文本和少量数据,不要试图传图片或文件。

Yggdrasil:覆盖式 Mesh 网络的 IPv6 互联

如果设备之间有某种物理链路(WiFi 直连、蓝牙、局域网),但没有公网 IP,Yggdrasil 可以在这些碎片化链路之上构建一个端到端的 IPv6 overlay 网络。每个节点自动获得一个 0200::/7 范围的 IPv6 地址,无需 DHCP,无需 NAT。

# Linux 上安装 Yggdrasil
sudo apt install yggdrasil-go   # Debian/Ubuntu
# 或从 GitHub Releases 下载二进制

# 生成配置文件
sudo yggdrasil -genconf > /etc/yggdrasil/yggdrasil.conf

# 启动(默认会自动发现局域网内的其他节点)
sudo yggdrasil -useconffile /etc/yggdrasil/yggdrasil.conf

# 查看自己的 Yggdrasil IPv6 地址
yggdrasil -getaddress
# 输出类似: 200:5e22:943e:e1f2:fd5e:892:3b4a:7c

# 测试连通性——ping 另一个 Yggdrasil 节点
ping6 200:abcd:1234:5678:9abc:def0:1234:5678

Yggdrasil 的关键特性:节点之间只需一个可达的物理路径(哪怕只是局域网),overlay 层会自动路由。这意味着你可以在断网的小区内,让所有邻居的设备通过 WiFi 局域网组成一个独立的 Yggdrasil 网络,在上面跑 HTTP、SSH、任何 TCP/UDP 应用。

# /etc/yggdrasil/yggdrasil.conf 关键配置片段
# 如果有公网节点可做中继,填入 Peers;纯局域网场景则留空,节点会自动发现同网段邻居
Peers: []
#  或指定已知的中继节点:
#  Peers:
#    - tls://1.2.3.4:1234

Listen: []
#  如果想让其他节点通过 WiFi 局域网连入:
#  Listen:
#    - tcp://0.0.0.0:12345

IfName: "auto"
#  auto 会自动创建虚拟网卡;也可指定如 "ygg0"

Briar:离线优先的端到端加密消息

Briar 专为高风险环境设计:记者、活动家、灾区居民。它的核心思路是——有网时用 Tor,没网时用蓝牙或 WiFi 直连,消息在本地存储并沿 mesh 逐跳传递。

Briar 是 Android 应用,直接从 F-Droid 或官网安装即可。没有服务器账号,身份完全本地生成。联系人通过面对面扫描二维码交换公钥——这个设计刻意避免了任何在线注册环节。

对于开发者,Briar 的消息传输协议(Bramble)有独立文档,可以参考其设计思路实现自己的离线消息系统:

  • Bramble Transport Protocol:基于 Tor 的加密传输
  • Bramble Sync Protocol:离线时的消息同步与去重
  • Bramble Rendezvous Protocol:节点发现

自建离线消息中继:一个最小 Python 示例

如果上述方案都不适用(比如硬件受限、团队技术栈统一),可以用最简单的方式搭建一个局域网消息中继。下面是一个不到 50 行的 Python 脚本,任何设备连入同一 WiFi 即可使用:

"""
离线消息中继服务器 + 客户端
同一局域网内运行 server,其他设备用 client 发送/接收消息
无需公网,无需注册
"""

import socket
import json
import threading
import time

SERVER_HOST = "0.0.0.0"   # 本机所有网卡
SERVER_PORT = 9900
MSG_FILE = "messages.json"  # 本地持久化

def load_messages():
    try:
        with open(MSG_FILE, "r") as f:
            return json.load(f)
    except FileNotFoundError:
        return []

def save_messages(msgs):
    with open(MSG_FILE, "w") as f:
        json.dump(msgs, f, ensure_ascii=False)

# ---------- 服务器 ----------
def handle_client(conn, addr):
    data = conn.recv(4096).decode()
    req = json.loads(data)
    if req["action"] == "send":
        msgs = load_messages()
        msgs.append({"from": req["name"], "text": req["text"], "ts": time.time()})
        save_messages(msgs)
        conn.sendall(json.dumps({"status": "ok", "count": len(msgs)}).encode())
    elif req["action"] == "recv":
        since = req.get("since", 0)
        msgs = load_messages()
        new = [m for m in msgs if m["ts"] > since]
        conn.sendall(json.dumps({"messages": new}).encode())
    conn.close()

def run_server():
    srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    srv.bind((SERVER_HOST, SERVER_PORT))
    srv.listen(5)
    print(f"中继服务器启动于 {SERVER_PORT},局域网内设备可连接")
    while True:
        conn, addr = srv.accept()
        threading.Thread(target=handle_client, args=(conn, addr), daemon=True).start()

# ---------- 客户端 ----------
def send_message(name, text, server_ip):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((server_ip, SERVER_PORT))
    s.sendall(json.dumps({"action": "send", "name": name, "text": text}).encode())
    resp = json.loads(s.recv(4096).decode())
    print(f"发送成功,服务器当前共 {resp['count']} 条消息")
    s.close()

def fetch_messages(since_ts, server_ip):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((server_ip, SERVER_PORT))
    s.sendall(json.dumps({"action": "recv", "since": since_ts}).encode())
    resp = json.loads(s.recv(8192).decode())
    for m in resp["messages"]:
        print(f"[{m['from']}] {m['text']}")
    s.close()
    return max((m["ts"] for m in resp["messages"]), default=since_ts)

# 使用方式:
#   在一台机器上: run_server()
#   其他机器上:   send_message("张三", "集合点在北门", "192.168.1.100")
#                 fetch_messages(0, "192.168.1.100")
if __name__ == "__main__":
    import sys
    if len(sys.argv) < 2:
        print("用法: python relay.py server | client <server_ip> send <名字> <消息> | client <server_ip> recv")
        sys.exit(1)
    mode = sys.argv[1]
    if mode == "server":
        run_server()
    elif mode == "client":
        sip = sys.argv[2]
        action = sys.argv[3]
        if action == "send":
            send_message(sys.argv[4], sys.argv[5], sip)
        elif action == "recv":
            fetch_messages(0, sip)

这个示例只做最基本的消息存储和拉取,没有加密、没有去重、没有多跳转发。生产环境请参考 Briar 的 Bramble 协议设计,或直接使用 Meshtastic / Yggdrasil。

选型建议与风险清单

场景 推荐方案 理由
户外/灾区,无任何网络 Meshtastic (LoRa) 硬件便宜,长距离,低功耗
断网小区/营地,有 WiFi 局域网 Yggdrasil 跑任何 TCP 应用,自动组网
高安全需求,面对面交换身份 Briar 端到端加密,无服务器,离线可用
快速原型,团队已有局域网 自建中继 最简单,但需自己补加密

几个需要注意的风险:

  • LoRa 频段合规:中国 433MHz 和 470MHz 频段有功率限制,发射功率超过 10mW 需要申请。Meshtastic 默认配置在合法范围内,不要随意调高功率。
  • Mesh 网络规模:Meshtastic 单频道约支持 40–80 个活跃节点,Yggdrasil 理论无上限但延迟随跳数增长。超过 100 足节点的场景需要仔细测试。
  • 物理安全:离线通信意味着设备本身是信任边界。Briar 的面对面密钥交换就是为了解决这个问题。自建中继方案中,任何连入局域网的设备都能读取消息——务必在应用层补 TLS 或消息级加密。
  • 持久化风险:本地存储的消息在设备丢失时不可恢复。关键数据要考虑多设备冗余。

互联网不是唯一的通信方式,但每种替代方案都有自己的边界条件。选对工具的前提是搞清楚你的断网场景到底属于哪一类——是完全没有物理链路,还是有链路但没有公网路由。答案不同,方案完全不同。


相关推荐