OpenHarmony 分布式软总线(DSoftBus)完整分析报告
基于
foundation/communication/dsoftbus/源码
目录
术语
| 缩写 | 全称 | 说明 |
|---|---|---|
| DSoftBus | Distributed Soft Bus | 分布式软总线(OpenHarmony 自研) |
| LNN | Local Network Node | 本地网络节点(组网管理子系统) |
| LDB | Local Distributed Ledger | 本地分布式账本(设备/业务信息库) |
| P2P | Peer-to-Peer | 点对点连接(Wi-Fi Direct/BLE) |
| QoS | Quality of Service | 服务质量(带宽/时延/可靠性) |
| Gear | Keepalive Gear | TCP 长连接保活模式档位 |
| BR | Basic Rate | 经典蓝牙(SPP 协议) |
| BLE | Bluetooth Low Energy | 低功耗蓝牙 |
| IPC | Inter-Process Communication | 进程间通信 |
| SA | System Ability | 系统服务(OHOS 概念) |
1. 概述
1.1 背景与目标
现实中多设备间通信方式多种多样(Wi-Fi、蓝牙等),不同的通信方式使用差异大,导致通信问题多;同时还面临设备间通信链路的融合共享和冲突无法处理等挑战。
分布式软总线(Distributed Soft Bus, DSoftBus) 是 OpenHarmony 提出的统一设备间通信中间件,位于 foundation/communication/dsoftbus/,其设计目标是:
┌────────────────────────────────────────────────────┐
│ 应用层:分布式任务调度 / 分布式数据 / 跨设备剪贴板 │
├────────────────────────────────────────────────────┤
│ DSoftBus(统一接口,不区分链路) │
│ ├─ 发现 → 找到附近设备 │
│ ├─ 连接 → 通过任意介质建立链路 │
│ ├─ 组网 → 维护统一逻辑网络 │
│ └─ 传输 → 消息/字节/流/文件传输 │
├────────────────────────────────────────────────────┤
│ 物理介质:Wi-Fi / Bluetooth / Ethernet / SLE │
└────────────────────────────────────────────────────┘
1.2 三大核心能力
| 能力 | 描述 | 用户使用 API |
|---|---|---|
| 发现连接 | 基于 Wi-Fi、蓝牙等介质的近场设备发现和连接 | PublishLNN / RefreshLNN |
| 设备组网 | 统一的设备组网与拓扑管理,为上层提供已组网设备列表 | JoinLNN / LeaveLNN / GetAllOnlineNodeInfo |
| 数据传输 | 基于已建立的组网通道进行消息/字节/流/文件传输 | Socket / SendBytes / SendStream / SendFile |
1.3 核心设计原则
- 统一抽象:应用层不感知底层是 Wi-Fi 还是蓝牙,仅看到
networkId这个逻辑设备标识 - 协议无关:核心代码不依赖具体协议实现,新增介质(如 SLE、NB-IoT)只需添加 adapter
- 软总线:"软"体现在不绑定特定硬件——通过软件协商和决策,挑选最佳链路
- 轻量 IPC:业务进程通过 SDK 跨进程调用软总线核心服务,避免每业务都重写通信协议
2. 系统架构
2.1 整体架构图
DSoftBus 物理架构分为四层(基于源码 README_zh.md:24 的官方架构图):
┌─────────────────────────────────────────────────────────────┐
│ 应用进程层(业务 SDK) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 跨设备剪贴板 │ │ 分布式任务调度 │ │ 分布式数据 │ ... │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ └─────────────────┼─────────────────┘ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ sdk/ (业务进程内调用,IPC 桥接) │ │
│ │ sdk/discovery sdk/bus_center sdk/transmission │ │
│ └──────────────────────────┬───────────────────────────┘ │
├─────────────────────────────┼───────────────────────────────┤
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ core/ (核心服务,软总线主进程) │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │
│ │ │discovery │ │connection│ │ LNN │ │ auth │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └────────┘ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ transmission (传输/会话) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────────┐ │ │
│ │ │ frame (框架,进程模型/任务调度/事件循环) │ │ │
│ │ └──────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ 适配层 adapter/ │
│ 适配各厂商 Wi-Fi 驱动 / 蓝牙协议栈 / 平台差异 │
├─────────────────────────────────────────────────────────────┤
│ 物理介质:Wi-Fi(802.11)/ Bluetooth(BR/EDR/BLE)/ │
│ Ethernet / SLE / Wi-Fi Direct P2P │
└─────────────────────────────────────────────────────────────┘
2.2 代码目录结构
源码根目录:foundation/communication/dsoftbus/
dsoftbus/
├── adapter/ # 适配层(厂商差异、不同 OS 平台)
├── components/ # 依赖组件代码
├── core/ # 核心代码(运行在软总线主进程)
│ ├── adapter/ # 核心层适配(与 adapter/ 区分)
│ ├── authentication/ # 认证(设备信任关系、密钥协商)
│ ├── bus_center/ # 组网(LNN 子系统)
│ │ ├── extend/ # 扩展功能(如分布式硬件协同)
│ │ ├── interface/ # 组网接口
│ │ ├── ipc/ # 组网 IPC 桥接
│ │ ├── lnn/ # 本地网络节点
│ │ │ ├── conn_mgr/ # 连接管理
│ │ │ ├── decision_center/ # 链路决策中心
│ │ │ ├── disc_mgr/ # 发现管理
│ │ │ ├── lane_hub/ # Lane 通道管理(链路选择)
│ │ │ ├── manager/ # 节点管理
│ │ │ ├── net_builder/ # 网络构建器(建立连接)
│ │ │ ├── net_buscenter/ # 组网服务中心
│ │ │ └── net_ledger/ # 账本(设备/业务信息持久化)
│ │ ├── monitor/ # 网络状态监控
│ │ ├── service/ # 组网服务入口
│ │ └── utils/ # 工具
│ ├── common/ # 通用代码
│ ├── connection/ # 物理连接层
│ │ ├── ble/ # BLE 连接
│ │ ├── br/ # 经典蓝牙 SPP 连接
│ │ ├── common/ # 连接公共
│ │ ├── general/ # 通用连接
│ │ ├── interface/ # 连接接口
│ │ ├── ipc/ # 连接 IPC
│ │ ├── manager/ # 连接管理器
│ │ ├── proxy/ # 连接代理(SDK 侧)
│ │ ├── sle/ # 星闪 SLE 连接
│ │ ├── tcp/ # TCP 连接
│ │ └── wifi_direct_cpp/ # Wi-Fi Direct P2P 连接(C++ 实现)
│ ├── discovery/ # 设备发现
│ ├── frame/ # 框架(进程管理、事件循环)
│ └── transmission/ # 数据传输
│ ├── broadcast/ # 广播(局域网发现)
│ ├── common/ # 传输公共
│ ├── interface/ # 传输接口
│ ├── ipc/ # 传输 IPC
│ ├── manager/ # 传输管理
│ ├── session/ # 会话管理
│ └── trans_channel/ # 传输通道
│ ├── auth/ # 通道认证
│ ├── common/ # 通道公共
│ ├── inner_session/ # 内部会话
│ ├── manager/ # 通道管理
│ ├── proxy/ # 通道代理
│ ├── tcp_direct/ # TCP 直连通道
│ └── udp_negotiation/ # UDP 协商(建链用)
├── interfaces/ # 对外接口(kits 头文件)
├── sdk/ # 业务进程 SDK(封装 IPC 调用)
│ ├── bus_center/ # 组网 SDK
│ ├── discovery/ # 发现 SDK
│ ├── frame/ # 框架 SDK
│ └── transmission/ # 传输 SDK
├── tests/ # 测试代码
└── tools/ # 工具
2.3 模块划分与依赖
DSoftBus core/ 下各模块的职责与依赖关系:
| 模块 | 职责 | 上游调用方 | 下游依赖 |
|---|---|---|---|
| discovery/ | 设备发现(capability 匹配、媒介分发) | sdk/discovery | 各种介质 adapter |
| connection/ | 物理连接管理(TCP/BLE/BR/SLE/Wi-Fi Direct) | sdk/transmission、lnn/net_builder | adapter/ 各介质驱动 |
| bus_center/lnn/ | 组网拓扑、networkId 分配、账本、链路决策 | sdk/bus_center、connection | net_ledger、auth |
| authentication/ | 设备凭证交换、信任关系校验 | lnn/net_builder(JoinLNN 后调用) | crypto 模块(位于 adapter) |
| transmission/ | 会话与传输通道(Socket、UDP 协商、流/文件传输) | sdk/transmission、connection | frame(任务调度) |
| frame/ | 进程模型、事件循环、任务调度 | 所有其他 core 模块 | OS 原生线程/锁 |
| common/ | 公共工具(日志、内存、JSON、字符串) | 所有其他 core 模块 | 无 |
依赖方向规则(core/ 下不可违反的约束):
┌────────────┐ ┌────────────┐ ┌────────────┐
│ discovery │ │ connection │ │ LNN │
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘
│ │ │
└────────────────┬┴─────────────────┘
▼
┌──────────────┐
│ transmission │
└──────────────┘
│
▼
┌──────────────┐
│ frame │ ← 基础设施,所有模块可依赖
└──────────────┘
关键约束:
- 单向依赖:discovery/connection/LNN → transmission → frame,禁止反向依赖(transmission 不调用 discovery)
- frame 不依赖业务模块:frame 只提供进程/线程/锁原语,不感知具体业务
- bus_center 是协调中枢:连接 discovery/connection/auth/transmission,但不直接实现任何物理层
- auth 是嵌入式服务:作为 lnn 内部模块被调用(JoinLNN 流程中),不暴露独立入口
对应用层 SDK 的依赖汇聚:
sdk/
discovery/ ─► core/discovery
bus_center/ ─► core/bus_center/lnn
transmission/ ─► core/transmission(间接通过 connection)
│
└──── sdk 内部可互相调用(如 transmission sdk 调用 bus_center sdk 获取 networkId)
sdk/ 下的三个子模块不直接通信,而是通过业务进程串接——SDK A 调用 core 后拿到结果,再调用 SDK B,形成"业务编排"。这避免 SDK 层出现循环依赖。
3. 设备发现(Discovery)
3.1 核心数据结构
来源:core/discovery/interface/
发布信息(PublishInfo):
typedef struct {
int publishId; // 发布消息 ID
DiscoverMode mode; // 发现模式(主动/被动)
ExchangeMedium medium; // 媒介(Wi-Fi/BLE/...)
ExchangeFreq freq; // 频率(低/中/高/超低)
const char *capability; // 设备能力标识(如 "ohos.distributed.devicelist")
unsigned char *capabilityData; // 自定义发布数据
unsigned int dataLen; // 自定义数据长度
bool ranging; // 是否需要测距
} PublishInfo;
发布回调:
typedef struct {
void (*OnPublishResult)(int publishId, PublishResult reason);
} IPublishCb;
发现信息(SubscribeInfo):与 PublishInfo 对偶。
发现回调:
typedef struct {
void (*OnDeviceFound)(const DeviceInfo *device);
void (*OnDiscoverResult)(int32_t refreshId, RefreshResult reason);
} IRefreshCallback;
3.2 发布流程
业务进程:调用 PublishLNN(pkgName, &PublishInfo, &cb)
│
▼
sdk/discovery/ (proxy 代理)
│ 序列化 PublishInfo + 包名 → IPC
▼
core/discovery/ (IPC stub)
│
▼
disc_mgr → 根据 medium 分发到具体媒介适配器
│
├── Wi-Fi → 通过 Wi-Fi P2P/Broadcast 帧携带 capability
├── BLE → 通过 BLE advertisement 包携带 capability
├── BR → 通过 SDP 记录携带 capability
└── SLE → 通过 SLE 广播帧携带 capability
│
▼
对端设备 discovery 接收后
│
├── 解码 capability
├── 匹配 SubscribeInfo.capability 过滤器
└── 命中 → 通过 OnDeviceFound 回调上送
3.3 发现流程
业务进程:调用 RefreshLNN(pkgName, &SubscribeInfo, &cb)
│
▼
disc_mgr 启动发现
│
├── 在指定媒介上监听(Wi-Fi 监听 / BLE 扫描 / ...)
├── 收到对端 publish 的 capability
├── 匹配本地 SubscribeInfo.capability
└── 命中 → DeviceInfo 上送给业务
3.4 介质与频率
// core/frame/standard/include/softbus_config_type.h
typedef enum {
AUTO = 0, // 自动选择
BLE, // 低功耗蓝牙
COAP, // CoAP 协议
USB, // USB
BUS_USB = USB,
WLAN, // Wi-Fi
WLAN2P5G, // 2.5G Wi-Fi
WLAN5G, // 5G Wi-Fi
LAN, // 网线
ETH = LAN, // 以太网
NFC, // NFC
BR, // 经典蓝牙
SLE, // 星闪
} ExchangeMedium;
typedef enum {
LOW = 0, // 低频
MID, // 中频
HIGH, // 高频
SUPER_HIGH, // 超高频
} ExchangeFreq;
频率含义:LOW 用于持续运行的发现(如设备列表维护),HIGH 用于临时发现(如点对点投屏)。
4. 设备连接(Connection)
4.1 连接地址类型
来源:core/connection/interface/
typedef enum {
CONNECTION_ADDR_WLAN = 0, // Wi-Fi IP:port
CONNECTION_ADDR_BR, // 经典蓝牙 MAC
CONNECTION_ADDR_BLE, // BLE MAC + UDID hash
CONNECTION_ADDR_ETH, // 以太网
CONNECTION_ADDR_MAX
} ConnectionAddrType;
typedef struct {
ConnectionAddrType type;
union {
struct BrAddr { char brMac[BT_MAC_LEN]; } br;
struct BleAddr {
char bleMac[BT_MAC_LEN];
uint8_t udidHash[UDID_HASH_LEN];
} ble;
struct IpAddr {
char ip[IP_STR_MAX_LEN];
uint16_t port;
} ip;
} info;
char peerUid[MAX_ACCOUNT_HASH_LEN];
} ConnectionAddr;
4.2 连接模块子模块
core/connection/ 下的子模块对应不同物理介质:
| 子模块 | 物理介质 | 特点 |
|---|---|---|
tcp/ |
TCP socket | 最通用,所有 IP 链路都可走 |
wifi_direct_cpp/ |
Wi-Fi Direct(P2P) | C++ 实现,设备直连不需 AP |
ble/ |
BLE(低功耗蓝牙) | 低功耗、近场,速率有限 |
br/ |
经典蓝牙 SPP | 兼容性最好,速率较低 |
sle/ |
星闪(Nearlink) | 华为自研低功耗通信 |
general/ |
通用连接(适配抽象) | 提供 ConnectA/ConnectB 抽象接口 |
common/ |
连接公共 | 数据结构、工具 |
manager/ |
连接管理器 | 维护所有活跃连接 |
proxy/ |
SDK 侧代理 | 业务进程通过它发起连接 |
ipc/ |
IPC 桥接 | 跨进程通信 |
interface/ |
抽象接口 | 各介质实现统一接口 |
4.3 Wi-Fi Direct 与 P2P 建链
core/connection/wifi_direct_cpp/ 是 DSoftBus 中最复杂的连接子模块(C++ 实现),负责 Wi-Fi P2P 设备发现、组 Owner 协商、GO 协商:
连接建立流程(简化)
│
├── 1. P2P 扫描(wifi_direct_cpp/adapter/)
│ ├── 监听对端 P2P 设备
│ └── 返回设备列表
│
├── 2. 协商角色(processor/)
│ ├── GO Negotiation(谁是 Group Owner)
│ ├── Provision Discovery(WPS 配网)
│ └── GO 决定 → 进入 Auth/Assoc 阶段
│
├── 3. DHCP 拿 IP
│ └── IP 分配后切换到 TCP 连接
│
└── 4. 通知 LNN net_builder 建立逻辑连接
4.4 BR/BLE 传统蓝牙连接
BR(经典蓝牙)连接:
│
├── SDP 查询 → 找到 SoftBus 服务 UUID
├── SPP RFCOMM 建立虚拟串口
├── 在 SPP 之上做 SoftBus 协议握手
└── 进入数据通信
BLE 连接:
│
├── GATT 服务发现
├── 订阅/通知模式数据交换(吞吐量低,适合小数据)
└── 适合作为 BR 不可用时的 fallback
5. 设备组网(Bus Center / LNN)
5.1 LNN 子模块构成
LNN(Local Network Node)是 DSoftBus 最庞大的子系统,位于 core/bus_center/lnn/:
| 子模块 | 功能 |
|---|---|
conn_mgr/ |
连接管理器(Connection Manager) |
decision_center/ |
链路决策中心(选择最佳链路) |
disc_mgr/ |
发现管理(与 LNN 集成的发现) |
lane_hub/ |
Lane 通道管理(业务消息选路) |
manager/ |
LNN 主管理(协调所有子模块) |
net_builder/ |
网络构建器(建立/拆除组网连接) |
net_buscenter/ |
组网服务总线(事件分发中心) |
net_ledger/ |
分布式账本(设备/业务信息持久化) |
5.2 JoinLNN / LeaveLNN 流程
// API
int32_t JoinLNN(const char *pkgName, ConnectionAddr *target, OnJoinLNNResult cb);
int32_t LeaveLNN(const char *pkgName, const char *networkId, OnLeaveLNNResult cb);
JoinLNN 详细流程:
业务进程:JoinLNN(pkgName, &addr, cb)
│
▼
sdk/bus_center/ (proxy)
│ IPC 转发
▼
core/bus_center/service/ (IPC stub)
│
▼
LnnNetBuilder
│
├── 1. 构造 NodeInfo(包含 addr、deviceId、udid 等)
├── 2. 调用 LnnConnMgr 发起连接
│ │
│ │ 根据 addr.type 分发:
│ ├── WLAN/ETH → TCP Connect
│ ├── BR → SPP 建立
│ ├── BLE → GATT 连接
│ └── Wi-Fi P2P → 触发 wifi_direct_cpp 建链
│
├── 3. 物理连接建立 → 进入认证阶段
│ └── auth 模块交换设备凭证
│
├── 4. 认证通过 → 分配 networkId
│ └── net_ledger 记录对端设备信息
│
├── 5. 通知业务
│ └── cb(addr, networkId, 0) // retCode=0 表示成功
│
└── 6. 发布 NODE_STATE_ONLINE 事件给所有订阅者
LeaveLNN 是对称的拆除流程:通知对端 → 关闭物理连接 → 回收 networkId → 通知业务。
5.3 NetworkId 分配机制
networkId 是 DSoftBus 中对端设备的逻辑标识符,由 LNN 在 JoinLNN 成功时分配,存放在 NodeBasicInfo.networkId。
特点:
- 长度
NETWORK_ID_BUF_LEN(典型 64~128 字节) - 设备间通信时使用 networkId 而不是 MAC/IP
- 解耦应用层与底层物理地址
- LNN 维护 networkId 与 ConnectionAddr 的双向映射
5.4 拓扑与设备状态
LNN 维护一个全网设备视图,事件类型:
#define EVENT_NODE_STATE_ONLINE 0x1 // 设备上线
#define EVENT_NODE_STATE_OFFLINE 0x02 // 设备下线
#define EVENT_NODE_STATE_INFO_CHANGED 0x04 // 设备信息变更
#define EVENT_NODE_STATUS_CHANGED 0x08 // 设备运行状态变更
#define EVENT_NODE_STATE_MASK 0xF
设备信息结构(NodeBasicInfo):
typedef struct {
char networkId[NETWORK_ID_BUF_LEN];
char deviceName[DEVICE_NAME_BUF_LEN];
uint16_t deviceTypeId; // 设备类型(手机/平板/PC/TV...)
} NodeBasicInfo;
注册设备状态回调:
int32_t RegNodeDeviceStateCb(const char *pkgName, INodeStateCb *callback);
5.5 心跳与 Gear 模式
为节省功耗,TCP 长连接保活参数可动态调整。Gear 模式:
typedef enum {
HIGH_FREQ_CYCLE = 30, // 30s 心跳
MID_FREQ_CYCLE = 60, // 60s 心跳
LOW_FREQ_CYCLE = 5 * 60, // 5 分钟
DEFAULT_FREQ_CYCLE = 10 * 60, // 10 分钟
} ModeCycle;
调用:
int32_t ShiftLNNGear(const char *pkgName, const char *callerId,
const char *targetNetworkId, const GearMode *mode);
应用通过 ShiftLNNGear 在不同场景切换保活档位:
- HIGH_FREQ:实时投屏/远程控制场景(30s 内感知对端断开)
- LOW_FREQ:后台数据同步场景(5min 心跳节省电量)
Gear 切换通过 IPC 调用服务端,策略管理模块调整 TCP keepalive 参数。
6. 认证(Authentication)
6.1 认证流程
DSoftBus 的认证机制保证只有已绑定的设备才能组网。位置:core/authentication/
JoinLNN 建链后
│
▼
auth 模块
│
├── 1. 交换设备凭证
│ ├── 设备 UDID(设备唯一标识)
│ ├── 用户 Account Hash
│ └── 设备认证 Token
│
├── 2. 验证对端是否已建立信任关系
│ ├── 查询本地 trust list
│ └── 是否在已绑定设备列表
│
├── 3. PIN 码/二维码确认(首次配对场景)
│
└── 4. 认证结果
├── 成功 → 上报 LNN net_ledger
└── 失败 → 关闭连接
6.2 信任关系建立
设备首次配对需要用户确认(PIN/二维码),配对成功后信任关系持久化到 distributed_ledger/,下次同账号设备上线时自动认证通过。
7. 数据传输(Transmission)
7.1 传输模块子结构
core/transmission/
├── broadcast/ # 局域网广播
├── common/ # 公共代码
├── interface/ # 传输接口
├── ipc/ # IPC
├── manager/ # 传输管理(统一入口)
├── session/ # 会话管理(业务层会话)
└── trans_channel/ # 传输通道(物理层通道)
├── auth/ # 通道认证
├── common/
├── inner_session/ # 内部会话
├── manager/ # 通道管理
├── proxy/ # 通道代理
├── tcp_direct/ # TCP 直连通道
└── udp_negotiation/ # UDP 协商(建链用)
7.2 Socket 抽象
DSoftBus 提供 Socket API 作为业务开发接口:
typedef struct {
char *name; // 本地 socket 名
char *peerName; // 对端 socket 名
char *peerNetworkId; // 对端 networkId
char *pkgName; // 调用方包名
TransDataType dataType; // 数据类型(消息/字节/流/文件)
} SocketInfo;
int32_t Socket(SocketInfo info); // 创建 socket
int32_t Listen(int32_t socket, const QosTV qos[], uint32_t qosCount,
const ISocketListener *listener);
int32_t Bind(int32_t socket, const QosTV qos[], uint32_t qosCount,
const ISocketListener *listener);
服务端 Listen、客户端 Bind 都接收 QoS 参数和回调监听器。
7.3 UDP 协商与通道建立
trans_channel/udp_negotiation/ 是 DSoftBus 关键设计——使用 UDP 完成通道协商,再用 TCP/UDP 传数据:
客户端:Bind(socket, qos, listener)
│
├── 1. 构造 NegotiateMessage(包含 qos 参数)
├── 2. 通过 UDP 发送到对端(固定端口)
│
▼
服务端:OnNegotiate 回调
│
├── 1. 解析 qos
├── 2. 业务确认(OnServiceNegotiate 回调)
├── 3. 回复 NegotiateReply
│
▼
客户端:收到 Reply → 协商成功
│
├── 1. 建立实际数据通道(TCP 或 UDP 取决于 qos)
├── 2. 通知业务 OnBind
│
▼
业务开始发送数据
7.4 四种数据类型
DSoftBus Socket 支持 4 种数据传输类型,对应不同业务场景:
| 类型 | 用途 | 典型场景 |
|---|---|---|
| Message | 单条完整消息(≤几十 KB) | 控制指令、状态通知 |
| Bytes | 字节流(非流式,无边界) | 任意二进制数据 |
| Stream | 数据流(分帧) | 实时音视频 |
| File | 文件传输 | 跨设备文件复制 |
API:
int32_t SendMessage(int32_t socket, const void *data, uint32_t len);
int32_t SendBytes(int32_t socket, const void *data, uint32_t len);
int32_t SendBytesAsync(int32_t socket, uint32_t dataSeq, const void *data, uint32_t len);
int32_t SendStream(int32_t socket, const StreamData *data, const StreamData *ext,
const StreamFrameInfo *param);
int32_t SendFile(int32_t socket, const char *sFileList[], const char *dFileList[],
uint32_t fileCnt);
7.5 QoS 服务质量
typedef enum {
QOS_TYPE_MIN_BW, // 最小带宽
QOS_TYPE_MAX_WAIT_TIMEOUT, // Bind 超时
QOS_TYPE_MIN_LATENCY, // 最低时延
QOS_TYPE_RTT_LEVEL, // 往返时延等级
QOS_TYPE_MAX_BUFFER, // 最大缓冲区
QOS_TYPE_FIRST_PACKAGE, // 首包大小
QOS_TYPE_MAX_IDLE_TIMEOUT, // 最大空闲时间
QOS_TYPE_TRANS_RELIABILITY, // 传输可靠性
QOS_TYPE_BUTT,
} QosType;
typedef struct {
QosType qos;
int32_t value;
} QosTV;
QoS 在 Listen/Bind 时传入,参与 UDP 协商过程,决定最终通道参数(带宽分配、流控策略等)。
8. 跨进程通信(IPC)机制
DSoftBus 核心服务运行在独立的软总线主进程(由 core/frame/ 的进程模型管理),业务进程通过 SDK 调用核心服务。
业务进程 软总线主进程
│ │
│ sdk/discovery/ │
│ proxy (客户端代理) │
│ │
│ IPC (序列化为 Parcel) │
│ ─────────────────────────────────► │
│ │ core/discovery/
│ │ IPC stub (服务端)
│ │
│ ◄───────────────────────────────── │
│ IPC reply (结果) │
│ │
│ sdk 回调 (OnPublishResult) │
▼ ▼
为什么需要 IPC?
- 业务进程不应包含 DSoftBus 全部代码(每个进程都初始化 BLE/Wi-Fi 驱动太重)
- 集中式管理所有连接(连接池、连接复用)
- 权限隔离(业务进程无法直接控制物理介质)
SDK 与核心服务通过 OHOS 的 IPC 框架(基于 communication_ipc 仓)通信。
9. 关键流程串联
9.1 设备间发送一条消息的完整链路
设备 A 的应用 设备 B 的应用
│ │
│ (1) PublishLNN("chat", ...) │ (1) RefreshLNN("chat", ...)
│ discovery │ discovery
│ │
│ (2) 协商建立 Wi-Fi Direct 连接 │
│ connection/wifi_direct_cpp/ │
│ │
│ (3) JoinLNN(target) │ 同步建链
│ LNN/ │
│ net_builder │
│ net_ledger (记账) │
│ auth (认证) │
│ → 分配 networkId │ → 分配 networkId
│ │
│ (4) Socket("chat", peerName, │ (4) Socket("chat", peerName,
│ peerNetworkId, MSG) │ peerNetworkId, MSG)
│ transmission │ transmission
│ trans_channel/ │
│ udp_negotiation │ (Listen 端)
│ manager │
│ session │
│ │
│ (5) Bind / Listen 完成 │
│ → 业务回调 OnBind │ → 业务回调 OnBind
│ │
│ (6) SendMessage(socket, "hi") │
│ trans_channel 实际传输 │
│ → 通过 TCP/UDP 通道发数据 │ → 收到 OnMessage 回调
│ │
│ (7) 业务处理 │ (7) 业务处理
│ │
│ (8) Shutdown(socket) │ (8) Shutdown(socket)
│ LeaveLNN(networkId) │ LeaveLNN(networkId)
│ StopPublishLNN / StopRefreshLNN │
9.2 设备上线触发链路
设备 B 上线
│
▼
LNN net_builder 监听到新连接
│
├── 1. 触发 auth 认证
│ └── 成功 → 进入步骤 2
│
├── 2. net_ledger 写入新设备信息
│ ├── deviceId, deviceName
│ ├── networkId
│ └── 业务能力(capability 列表)
│
├── 3. 触发 EVENT_NODE_STATE_ONLINE 事件
│ └── 通知所有 RegNodeDeviceStateCb 注册者
│
└── 4. 业务感知新设备
├── 如果之前 SubscribeInfo 匹配 → OnDeviceFound 回调
└── 业务可发起 JoinLNN
10. 与 Android/Nearby/Apple 体系对比
| 维度 | OpenHarmony DSoftBus | Android Nearby/Discovery | Apple MultipeerConnectivity |
|---|---|---|---|
| 架构 | 独立子系统 + SDK 模式 | com.google.android.gms.nearby |
iOS/macOS 系统级 |
| 协议 | 自研 SoftBus 协议(基于 UDP/TCP) | Protobuf + Wi-Fi/BLE | 自研协议(Bonjour-like) |
| 发现机制 | capability 字符串匹配 | Service ID | Service Type |
| 传输类型 | Message/Bytes/Stream/File | Bytes/File | Stream/Reliable |
| 组网概念 | networkId + LNN 拓扑 | 无显式组网 | P2P session |
| 权限模型 | DISTRIBUTED_DATASYNC 等 |
BLUETOOTH/NEARBY | 用户授权 |
| 后台保活 | Gear 模式 + 心跳 | ForegroundService | 系统调度 |
| 链路切换 | decision_center 自动 | 手动选择 | 手动选择 |
| 跨进程 | IPC 到软总线主进程 | 进程内 | 进程内 |
DSoftBus 的独特设计:显式的 LNN 组网拓扑 + Gear 心跳档位 是 Android/Apple 体系中没有的。
11. 设计模式与亮点
- 分层抽象:SDK / Core / Adapter / 物理介质四层,向上屏蔽物理细节
- 协议无关:所有协议走 connection/iface 抽象接口,新增介质(如 SLE)只需实现 adapter
- 分布式账本(Ledger):设备/业务信息持久化,进程崩溃重启后能恢复网络视图
- Gear 模式:业务可动态调整保活策略,平衡实时性与功耗
- 软总线 IPC:业务进程通过 SDK 跨进程访问,零拷贝高效
- Lane 通道(
lane_hub/):细粒度的链路选择,可针对不同业务消息选不同链路
12. 总结
12.1 核心链路
DSoftBus 的核心链路:
发现 (capability 匹配) → 连接 (物理建链) → 认证 (信任验证) →
组网 (LNN + networkId) → 传输 (Socket 4 种数据类型)
12.2 关键设计点
- 统一抽象层:应用感知 networkId,不感知 Wi-Fi/BLE;切换链路无感
- LNN 拓扑管理:把"近场设备"组织成统一网络,分配逻辑 ID
- Gear 心跳档位:业务可控的功耗-实时性平衡
- 分布式账本:跨进程崩溃后能恢复网络状态
- 协议无关:新增物理介质(如 SLE)只需 adapter 层实现
- IPC 主进程模型:避免每业务都加载完整 BLE/Wi-Fi 栈,集中管理连接
12.3 FAQ
Q: DSoftBus 与传统 TCP socket 编程有何区别?
A: 传统 socket 编程要自己处理 IP 寻址、连接管理、断线重连、安全加密等。DSoftBus 把这些封装成"发现 → 认证 → 组网 → 传输"四步接口,业务只需关注数据本身。
Q: 为什么需要显式的 JoinLNN/LeaveLNN 阶段?
A: 因为分布式场景下,设备"在物理上能通"不等于"在业务上能组网"。JoinLNN 触发认证、记账、networkId 分配,让上层建立一个有明确生命周期的"逻辑连接"。
Q: Gear 模式会影响电量吗?
A: 是。HIGH_FREQ 30s 心跳会持续唤醒网络芯片;LOW_FREQ 5min 心跳大幅降低唤醒次数。典型做法是用户主动投屏时切到 HIGH_FREQ,后台数据同步时切到 LOW_FREQ。
Q: 业务如何知道对端是否在线?
A: 通过 RegNodeDeviceStateCb 注册 EVENT_NODE_STATE_ONLINE/OFFLINE 回调;LNN 在设备连接/断开时主动通知。
Q: DSoftBus 跨进程调用的开销大吗?
A: SDK 与核心服务通过 OHOS IPC 框架(基于 Binder 改造)通信,单次 IPC 微秒级,业务可忽略。代价是业务不能直接持有连接对象,必须用 socketId 标识。
12.4 核心文件速查表
| 模块 | 路径 | 功能 |
|---|---|---|
| 发现 SDK | sdk/discovery/ |
业务侧发布/发现接口 |
| 发现核心 | core/discovery/ |
capability 匹配、媒介分发 |
| 连接 SDK | sdk/transmission/ |
Socket/Listen/Bind |
| 连接核心 | core/connection/ |
物理链路管理(BLE/BR/Wi-Fi Direct/TCP/SLE) |
| Wi-Fi P2P | core/connection/wifi_direct_cpp/ |
GO 协商、P2P 建链 |
| LNN | core/bus_center/lnn/ |
组网、networkId、账本、链路决策 |
| Ledger | core/bus_center/lnn/net_ledger/ |
设备/业务信息持久化 |
| 认证 | core/authentication/ |
设备信任、密钥交换 |
| 传输核心 | core/transmission/ |
会话、通道、UDP 协商 |
| UDP 协商 | core/transmission/trans_channel/udp_negotiation/ |
Listen/Bind 协议握手 |
| 框架 | core/frame/ |
进程模型、事件循环、任务调度 |
| 适配层 | adapter/ |
各厂商/平台差异屏蔽 |

浙公网安备 33010602011771号