1e41f4b71Sopenharmony_ci# Socket 连接 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci## 简介 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ciSocket 连接主要是通过 Socket 进行数据传输,支持 TCP/UDP/Multicast/TLS 协议。 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci## 基本概念 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci- Socket:套接字,就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。 10e41f4b71Sopenharmony_ci- TCP:传输控制协议(Transmission Control Protocol)。是一种面向连接的、可靠的、基于字节流的传输层通信协议。 11e41f4b71Sopenharmony_ci- UDP:用户数据报协议(User Datagram Protocol)。是一个简单的面向消息的传输层,不需要连接。 12e41f4b71Sopenharmony_ci- Multicast:多播,基于UDP的一种通信模式,用于实现组内所有设备之间广播形式的通信。 13e41f4b71Sopenharmony_ci- LocalSocket:本地套接字,IPC(Inter-Process Communication)进程间通信的一种,实现设备内进程之间相互通信,无需网络。 14e41f4b71Sopenharmony_ci- TLS:安全传输层协议(Transport Layer Security)。用于在两个通信应用程序之间提供保密性和数据完整性。 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci## 场景介绍 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci应用通过 Socket 进行数据传输,支持 TCP/UDP/Multicast/TLS 协议。主要场景有: 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci- 应用通过 TCP/UDP Socket进行数据传输 21e41f4b71Sopenharmony_ci- 应用通过 TCP Socket Server 进行数据传输 22e41f4b71Sopenharmony_ci- 应用通过 Multicast Socket 进行数据传输 23e41f4b71Sopenharmony_ci- 应用通过 Local Socket进行数据传输 24e41f4b71Sopenharmony_ci- 应用通过 Local Socket Server 进行数据传输 25e41f4b71Sopenharmony_ci- 应用通过 TLS Socket 进行加密数据传输 26e41f4b71Sopenharmony_ci- 应用通过 TLS Socket Server 进行加密数据传输 27e41f4b71Sopenharmony_ci 28e41f4b71Sopenharmony_ci## 接口说明 29e41f4b71Sopenharmony_ci 30e41f4b71Sopenharmony_ci完整的 API 说明以及实例代码请参考:[Socket 连接](../reference/apis-network-kit/js-apis-socket.md)。 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ciSocket 连接主要由 socket 模块提供。具体接口说明如下表。 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci| 接口名 | 描述 | 35e41f4b71Sopenharmony_ci| ---------------------------------- | ------------------------------------------------------------------------------ | 36e41f4b71Sopenharmony_ci| constructUDPSocketInstance() | 创建一个 UDPSocket 对象。 | 37e41f4b71Sopenharmony_ci| constructTCPSocketInstance() | 创建一个 TCPSocket 对象。 | 38e41f4b71Sopenharmony_ci| constructTCPSocketServerInstance() | 创建一个 TCPSocketServer 对象。 | 39e41f4b71Sopenharmony_ci| constructMulticastSocketInstance() | 创建一个 MulticastSocket 对象。 | 40e41f4b71Sopenharmony_ci| constructLocalSocketInstance() | 创建一个 LocalSocket 对象。 | 41e41f4b71Sopenharmony_ci| constructLocalSocketServerInstance() | 创建一个 LocalSocketServer 对象。 | 42e41f4b71Sopenharmony_ci| listen() | 绑定、监听并启动服务,接收客户端的连接请求。(仅 TCP/LocalSocket 支持)。 | 43e41f4b71Sopenharmony_ci| bind() | 绑定 IP 地址和端口,或是绑定本地套接字路径。 | 44e41f4b71Sopenharmony_ci| send() | 发送数据。 | 45e41f4b71Sopenharmony_ci| close() | 关闭连接。 | 46e41f4b71Sopenharmony_ci| getState() | 获取 Socket 状态。 | 47e41f4b71Sopenharmony_ci| connect() | 连接到指定的 IP 地址和端口,或是连接到本地套接字(仅 TCP/LocalSocket 支持)。 | 48e41f4b71Sopenharmony_ci| getRemoteAddress() | 获取对端 Socket 地址(仅 TCP 支持,需要先调用 connect 方法)。 | 49e41f4b71Sopenharmony_ci| setExtraOptions() | 设置 Socket 连接的其他属性。 | 50e41f4b71Sopenharmony_ci| getExtraOptions() | 获取 Socket 连接的其他属性(仅 LocalSocket 支持)。 | 51e41f4b71Sopenharmony_ci| addMembership() | 加入到指定的多播组 IP 中 (仅 Multicast 支持)。 | 52e41f4b71Sopenharmony_ci| dropMembership() | 从指定的多播组 IP 中退出 (仅 Multicast 支持)。 | 53e41f4b71Sopenharmony_ci| setMulticastTTL() | 设置数据传输跳数 TTL (仅 Multicast 支持)。 | 54e41f4b71Sopenharmony_ci| getMulticastTTL() | 获取数据传输跳数 TTL (仅 Multicast 支持)。 | 55e41f4b71Sopenharmony_ci| setLoopbackMode() | 设置回环模式,允许主机在本地循环接收自己发送的多播数据包 (仅 Multicast 支持)。 | 56e41f4b71Sopenharmony_ci| getLoopbackMode() | 获取回环模式开启或关闭的状态 (仅 Multicast 支持)。 | 57e41f4b71Sopenharmony_ci| on(type: 'message') | 订阅 Socket 连接的接收消息事件。 | 58e41f4b71Sopenharmony_ci| off(type: 'message') | 取消订阅 Socket 连接的接收消息事件。 | 59e41f4b71Sopenharmony_ci| on(type: 'close') | 订阅 Socket 连接的关闭事件。 | 60e41f4b71Sopenharmony_ci| off(type: 'close') | 取消订阅 Socket 连接的关闭事件。 | 61e41f4b71Sopenharmony_ci| on(type: 'error') | 订阅 Socket 连接的 Error 事件。 | 62e41f4b71Sopenharmony_ci| off(type: 'error') | 取消订阅 Socket 连接的 Error 事件。 | 63e41f4b71Sopenharmony_ci| on(type: 'listening') | 订阅 UDPSocket 连接的数据包消息事件(仅 UDP 支持)。 | 64e41f4b71Sopenharmony_ci| off(type: 'listening') | 取消订阅 UDPSocket 连接的数据包消息事件(仅 UDP 支持)。 | 65e41f4b71Sopenharmony_ci| on(type: 'connect') | 订阅 Socket 的连接事件(仅 TCP/LocalSocket 支持)。 | 66e41f4b71Sopenharmony_ci| off(type: 'connect') | 取消订阅 Socket 的连接事件(仅 TCP/LocalSocket 支持)。 | 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ciTLS Socket 连接主要由 tls_socket 模块提供。具体接口说明如下表。 69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci| 接口名 | 功能描述 | 71e41f4b71Sopenharmony_ci| ---------------------------- | ---------------------------------------------------------- | 72e41f4b71Sopenharmony_ci| constructTLSSocketInstance() | 创建一个 TLSSocket 对象。 | 73e41f4b71Sopenharmony_ci| bind() | 绑定 IP 地址和端口号。 | 74e41f4b71Sopenharmony_ci| close(type: 'error') | 关闭连接。 | 75e41f4b71Sopenharmony_ci| connect() | 连接到指定的 IP 地址和端口。 | 76e41f4b71Sopenharmony_ci| getCertificate() | 返回表示本地证书的对象。 | 77e41f4b71Sopenharmony_ci| getCipherSuite() | 返回包含协商的密码套件信息的列表。 | 78e41f4b71Sopenharmony_ci| getProtocol() | 返回包含当前连接协商的 SSL/TLS 协议版本的字符串。 | 79e41f4b71Sopenharmony_ci| getRemoteAddress() | 获取 TLSSocket 连接的对端地址。 | 80e41f4b71Sopenharmony_ci| getRemoteCertificate() | 返回表示对等证书的对象。 | 81e41f4b71Sopenharmony_ci| getSignatureAlgorithms() | 在服务器和客户端之间共享的签名算法列表,按优先级降序排列。 | 82e41f4b71Sopenharmony_ci| getState() | 获取 TLSSocket 连接的状态。 | 83e41f4b71Sopenharmony_ci| off(type: 'close') | 取消订阅 TLSSocket 连接的关闭事件。 | 84e41f4b71Sopenharmony_ci| off(type: 'error') | 取消订阅 TLSSocket 连接的 Error 事件。 | 85e41f4b71Sopenharmony_ci| off(type: 'message') | 取消订阅 TLSSocket 连接的接收消息事件。 | 86e41f4b71Sopenharmony_ci| on(type: 'close') | 订阅 TLSSocket 连接的关闭事件。 | 87e41f4b71Sopenharmony_ci| on(type: 'error') | 订阅 TLSSocket 连接的 Error 事件。 | 88e41f4b71Sopenharmony_ci| on(type: 'message') | 订阅 TLSSocket 连接的接收消息事件。 | 89e41f4b71Sopenharmony_ci| send() | 发送数据。 | 90e41f4b71Sopenharmony_ci| setExtraOptions() | 设置 TLSSocket 连接的其他属性。 | 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci## 应用 TCP/UDP 协议进行通信 93e41f4b71Sopenharmony_ci 94e41f4b71Sopenharmony_ciUDP 与 TCP 流程大体类似,下面以 TCP 为例: 95e41f4b71Sopenharmony_ci 96e41f4b71Sopenharmony_ci1. import 需要的 socket 模块。 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_ci2. 创建一个 TCPSocket 连接,返回一个 TCPSocket 对象。 99e41f4b71Sopenharmony_ci 100e41f4b71Sopenharmony_ci3. (可选)订阅 TCPSocket 相关的订阅事件。 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci4. 绑定 IP 地址和端口,端口可以指定或由系统随机分配。 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci5. 连接到指定的 IP 地址和端口。 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci6. 发送数据。 107e41f4b71Sopenharmony_ci 108e41f4b71Sopenharmony_ci7. Socket 连接使用完毕后,主动关闭。 109e41f4b71Sopenharmony_ci 110e41f4b71Sopenharmony_ci```ts 111e41f4b71Sopenharmony_ciimport { socket } from '@kit.NetworkKit'; 112e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ciclass SocketInfo { 115e41f4b71Sopenharmony_ci message: ArrayBuffer = new ArrayBuffer(1); 116e41f4b71Sopenharmony_ci remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo; 117e41f4b71Sopenharmony_ci} 118e41f4b71Sopenharmony_ci// 创建一个TCPSocket连接,返回一个TCPSocket对象。 119e41f4b71Sopenharmony_cilet tcp: socket.TCPSocket = socket.constructTCPSocketInstance(); 120e41f4b71Sopenharmony_citcp.on('message', (value: SocketInfo) => { 121e41f4b71Sopenharmony_ci console.log("on message"); 122e41f4b71Sopenharmony_ci let buffer = value.message; 123e41f4b71Sopenharmony_ci let dataView = new DataView(buffer); 124e41f4b71Sopenharmony_ci let str = ""; 125e41f4b71Sopenharmony_ci for (let i = 0; i < dataView.byteLength; ++i) { 126e41f4b71Sopenharmony_ci str += String.fromCharCode(dataView.getUint8(i)); 127e41f4b71Sopenharmony_ci } 128e41f4b71Sopenharmony_ci console.log("on connect received:" + str); 129e41f4b71Sopenharmony_ci}); 130e41f4b71Sopenharmony_citcp.on('connect', () => { 131e41f4b71Sopenharmony_ci console.log("on connect"); 132e41f4b71Sopenharmony_ci}); 133e41f4b71Sopenharmony_citcp.on('close', () => { 134e41f4b71Sopenharmony_ci console.log("on close"); 135e41f4b71Sopenharmony_ci}); 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci// 绑定本地IP地址和端口。 138e41f4b71Sopenharmony_cilet ipAddress : socket.NetAddress = {} as socket.NetAddress; 139e41f4b71Sopenharmony_ciipAddress.address = "192.168.xxx.xxx"; 140e41f4b71Sopenharmony_ciipAddress.port = 1234; 141e41f4b71Sopenharmony_citcp.bind(ipAddress, (err: BusinessError) => { 142e41f4b71Sopenharmony_ci if (err) { 143e41f4b71Sopenharmony_ci console.log('bind fail'); 144e41f4b71Sopenharmony_ci return; 145e41f4b71Sopenharmony_ci } 146e41f4b71Sopenharmony_ci console.log('bind success'); 147e41f4b71Sopenharmony_ci 148e41f4b71Sopenharmony_ci // 连接到指定的IP地址和端口。 149e41f4b71Sopenharmony_ci ipAddress.address = "192.168.xxx.xxx"; 150e41f4b71Sopenharmony_ci ipAddress.port = 5678; 151e41f4b71Sopenharmony_ci 152e41f4b71Sopenharmony_ci let tcpConnect : socket.TCPConnectOptions = {} as socket.TCPConnectOptions; 153e41f4b71Sopenharmony_ci tcpConnect.address = ipAddress; 154e41f4b71Sopenharmony_ci tcpConnect.timeout = 6000; 155e41f4b71Sopenharmony_ci 156e41f4b71Sopenharmony_ci tcp.connect(tcpConnect).then(() => { 157e41f4b71Sopenharmony_ci console.log('connect success'); 158e41f4b71Sopenharmony_ci let tcpSendOptions: socket.TCPSendOptions = { 159e41f4b71Sopenharmony_ci data: 'Hello, server!' 160e41f4b71Sopenharmony_ci } 161e41f4b71Sopenharmony_ci tcp.send(tcpSendOptions).then(() => { 162e41f4b71Sopenharmony_ci console.log('send success'); 163e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 164e41f4b71Sopenharmony_ci console.log('send fail'); 165e41f4b71Sopenharmony_ci }); 166e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 167e41f4b71Sopenharmony_ci console.log('connect fail'); 168e41f4b71Sopenharmony_ci }); 169e41f4b71Sopenharmony_ci}); 170e41f4b71Sopenharmony_ci 171e41f4b71Sopenharmony_ci// 连接使用完毕后,主动关闭。取消相关事件的订阅。 172e41f4b71Sopenharmony_cisetTimeout(() => { 173e41f4b71Sopenharmony_ci tcp.close().then(() => { 174e41f4b71Sopenharmony_ci console.log('close success'); 175e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 176e41f4b71Sopenharmony_ci console.log('close fail'); 177e41f4b71Sopenharmony_ci }); 178e41f4b71Sopenharmony_ci tcp.off('message'); 179e41f4b71Sopenharmony_ci tcp.off('connect'); 180e41f4b71Sopenharmony_ci tcp.off('close'); 181e41f4b71Sopenharmony_ci}, 30 * 1000); 182e41f4b71Sopenharmony_ci``` 183e41f4b71Sopenharmony_ci 184e41f4b71Sopenharmony_ci## 应用通过 TCP Socket Server 进行数据传输 185e41f4b71Sopenharmony_ci 186e41f4b71Sopenharmony_ci服务端 TCP Socket 流程: 187e41f4b71Sopenharmony_ci 188e41f4b71Sopenharmony_ci1. import 需要的 socket 模块。 189e41f4b71Sopenharmony_ci2. 创建一个 TCPSocketServer 连接,返回一个 TCPSocketServer 对象。 190e41f4b71Sopenharmony_ci3. 绑定本地 IP 地址和端口,监听并接受与此套接字建立的客户端 TCPSocket 连接。 191e41f4b71Sopenharmony_ci4. 订阅 TCPSocketServer 的 connect 事件,用于监听客户端的连接状态。 192e41f4b71Sopenharmony_ci5. 客户端与服务端建立连接后,返回一个 TCPSocketConnection 对象,用于与客户端通信。 193e41f4b71Sopenharmony_ci6. 订阅 TCPSocketConnection 相关的事件,通过 TCPSocketConnection 向客户端发送数据。 194e41f4b71Sopenharmony_ci7. 主动关闭与客户端的连接。 195e41f4b71Sopenharmony_ci8. 取消 TCPSocketConnection 和 TCPSocketServer 相关事件的订阅。 196e41f4b71Sopenharmony_ci 197e41f4b71Sopenharmony_ci```ts 198e41f4b71Sopenharmony_ciimport { socket } from '@kit.NetworkKit'; 199e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 200e41f4b71Sopenharmony_ci 201e41f4b71Sopenharmony_ci// 创建一个TCPSocketServer连接,返回一个TCPSocketServer对象。 202e41f4b71Sopenharmony_cilet tcpServer: socket.TCPSocketServer = socket.constructTCPSocketServerInstance(); 203e41f4b71Sopenharmony_ci// 绑定本地IP地址和端口,进行监听 204e41f4b71Sopenharmony_ci 205e41f4b71Sopenharmony_cilet ipAddress : socket.NetAddress = {} as socket.NetAddress; 206e41f4b71Sopenharmony_ciipAddress.address = "192.168.xxx.xxx"; 207e41f4b71Sopenharmony_ciipAddress.port = 4651; 208e41f4b71Sopenharmony_citcpServer.listen(ipAddress).then(() => { 209e41f4b71Sopenharmony_ci console.log('listen success'); 210e41f4b71Sopenharmony_ci}).catch((err: BusinessError) => { 211e41f4b71Sopenharmony_ci console.log('listen fail'); 212e41f4b71Sopenharmony_ci}); 213e41f4b71Sopenharmony_ci 214e41f4b71Sopenharmony_ciclass SocketInfo { 215e41f4b71Sopenharmony_ci message: ArrayBuffer = new ArrayBuffer(1); 216e41f4b71Sopenharmony_ci remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo; 217e41f4b71Sopenharmony_ci} 218e41f4b71Sopenharmony_ci// 订阅TCPSocketServer的connect事件 219e41f4b71Sopenharmony_citcpServer.on("connect", (client: socket.TCPSocketConnection) => { 220e41f4b71Sopenharmony_ci // 订阅TCPSocketConnection相关的事件 221e41f4b71Sopenharmony_ci client.on("close", () => { 222e41f4b71Sopenharmony_ci console.log("on close success"); 223e41f4b71Sopenharmony_ci }); 224e41f4b71Sopenharmony_ci client.on("message", (value: SocketInfo) => { 225e41f4b71Sopenharmony_ci let buffer = value.message; 226e41f4b71Sopenharmony_ci let dataView = new DataView(buffer); 227e41f4b71Sopenharmony_ci let str = ""; 228e41f4b71Sopenharmony_ci for (let i = 0; i < dataView.byteLength; ++i) { 229e41f4b71Sopenharmony_ci str += String.fromCharCode(dataView.getUint8(i)); 230e41f4b71Sopenharmony_ci } 231e41f4b71Sopenharmony_ci console.log("received message--:" + str); 232e41f4b71Sopenharmony_ci console.log("received address--:" + value.remoteInfo.address); 233e41f4b71Sopenharmony_ci console.log("received family--:" + value.remoteInfo.family); 234e41f4b71Sopenharmony_ci console.log("received port--:" + value.remoteInfo.port); 235e41f4b71Sopenharmony_ci console.log("received size--:" + value.remoteInfo.size); 236e41f4b71Sopenharmony_ci }); 237e41f4b71Sopenharmony_ci 238e41f4b71Sopenharmony_ci // 向客户端发送数据 239e41f4b71Sopenharmony_ci let tcpSendOptions : socket.TCPSendOptions = {} as socket.TCPSendOptions; 240e41f4b71Sopenharmony_ci tcpSendOptions.data = 'Hello, client!'; 241e41f4b71Sopenharmony_ci client.send(tcpSendOptions).then(() => { 242e41f4b71Sopenharmony_ci console.log('send success'); 243e41f4b71Sopenharmony_ci }).catch((err: Object) => { 244e41f4b71Sopenharmony_ci console.error('send fail: ' + JSON.stringify(err)); 245e41f4b71Sopenharmony_ci }); 246e41f4b71Sopenharmony_ci 247e41f4b71Sopenharmony_ci // 关闭与客户端的连接 248e41f4b71Sopenharmony_ci client.close().then(() => { 249e41f4b71Sopenharmony_ci console.log('close success'); 250e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 251e41f4b71Sopenharmony_ci console.log('close fail'); 252e41f4b71Sopenharmony_ci }); 253e41f4b71Sopenharmony_ci 254e41f4b71Sopenharmony_ci // 取消TCPSocketConnection相关的事件订阅 255e41f4b71Sopenharmony_ci setTimeout(() => { 256e41f4b71Sopenharmony_ci client.off("message"); 257e41f4b71Sopenharmony_ci client.off("close"); 258e41f4b71Sopenharmony_ci }, 10 * 1000); 259e41f4b71Sopenharmony_ci}); 260e41f4b71Sopenharmony_ci 261e41f4b71Sopenharmony_ci// 取消TCPSocketServer相关的事件订阅 262e41f4b71Sopenharmony_cisetTimeout(() => { 263e41f4b71Sopenharmony_ci tcpServer.off("connect"); 264e41f4b71Sopenharmony_ci}, 30 * 1000); 265e41f4b71Sopenharmony_ci``` 266e41f4b71Sopenharmony_ci 267e41f4b71Sopenharmony_ci## 应用通过 Multicast Socket 进行数据传输 268e41f4b71Sopenharmony_ci 269e41f4b71Sopenharmony_ci1. import 需要的 socket 模块。 270e41f4b71Sopenharmony_ci 271e41f4b71Sopenharmony_ci2. 创建 multicastSocket 多播对象。 272e41f4b71Sopenharmony_ci 273e41f4b71Sopenharmony_ci3. 指定多播 IP 与端口,加入多播组。 274e41f4b71Sopenharmony_ci 275e41f4b71Sopenharmony_ci4. 开启消息 message 监听。 276e41f4b71Sopenharmony_ci 277e41f4b71Sopenharmony_ci5. 发送数据,数据以广播的形式传输,同一多播组中已经开启消息 message 监听的多播对象都会接收到数据。 278e41f4b71Sopenharmony_ci 279e41f4b71Sopenharmony_ci6. 关闭 message 消息的监听。 280e41f4b71Sopenharmony_ci 281e41f4b71Sopenharmony_ci7. 退出多播组。 282e41f4b71Sopenharmony_ci 283e41f4b71Sopenharmony_ci```ts 284e41f4b71Sopenharmony_ciimport { socket } from '@kit.NetworkKit'; 285e41f4b71Sopenharmony_ci 286e41f4b71Sopenharmony_ci// 创建Multicast对象 287e41f4b71Sopenharmony_cilet multicast: socket.MulticastSocket = socket.constructMulticastSocketInstance(); 288e41f4b71Sopenharmony_ci 289e41f4b71Sopenharmony_cilet addr : socket.NetAddress = { 290e41f4b71Sopenharmony_ci address: '239.255.0.1', 291e41f4b71Sopenharmony_ci port: 32123, 292e41f4b71Sopenharmony_ci family: 1 293e41f4b71Sopenharmony_ci} 294e41f4b71Sopenharmony_ci 295e41f4b71Sopenharmony_ci// 加入多播组 296e41f4b71Sopenharmony_cimulticast.addMembership(addr).then(() => { 297e41f4b71Sopenharmony_ci console.log('addMembership success'); 298e41f4b71Sopenharmony_ci}).catch((err: Object) => { 299e41f4b71Sopenharmony_ci console.log('addMembership fail'); 300e41f4b71Sopenharmony_ci}); 301e41f4b71Sopenharmony_ci 302e41f4b71Sopenharmony_ci// 开启监听消息数据,将接收到的ArrayBuffer类型数据转换为String 303e41f4b71Sopenharmony_ciclass SocketInfo { 304e41f4b71Sopenharmony_ci message: ArrayBuffer = new ArrayBuffer(1); 305e41f4b71Sopenharmony_ci remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo; 306e41f4b71Sopenharmony_ci} 307e41f4b71Sopenharmony_cimulticast.on('message', (data: SocketInfo) => { 308e41f4b71Sopenharmony_ci console.info('接收的数据: ' + JSON.stringify(data)) 309e41f4b71Sopenharmony_ci const uintArray = new Uint8Array(data.message) 310e41f4b71Sopenharmony_ci let str = '' 311e41f4b71Sopenharmony_ci for (let i = 0; i < uintArray.length; ++i) { 312e41f4b71Sopenharmony_ci str += String.fromCharCode(uintArray[i]) 313e41f4b71Sopenharmony_ci } 314e41f4b71Sopenharmony_ci console.info(str) 315e41f4b71Sopenharmony_ci}) 316e41f4b71Sopenharmony_ci 317e41f4b71Sopenharmony_ci// 发送数据 318e41f4b71Sopenharmony_cimulticast.send({ data:'Hello12345', address: addr }).then(() => { 319e41f4b71Sopenharmony_ci console.log('send success'); 320e41f4b71Sopenharmony_ci}).catch((err: Object) => { 321e41f4b71Sopenharmony_ci console.log('send fail, ' + JSON.stringify(err)); 322e41f4b71Sopenharmony_ci}); 323e41f4b71Sopenharmony_ci 324e41f4b71Sopenharmony_ci// 关闭消息的监听 325e41f4b71Sopenharmony_cimulticast.off('message') 326e41f4b71Sopenharmony_ci 327e41f4b71Sopenharmony_ci// 退出多播组 328e41f4b71Sopenharmony_cimulticast.dropMembership(addr).then(() => { 329e41f4b71Sopenharmony_ci console.log('drop membership success'); 330e41f4b71Sopenharmony_ci}).catch((err: Object) => { 331e41f4b71Sopenharmony_ci console.log('drop membership fail'); 332e41f4b71Sopenharmony_ci}); 333e41f4b71Sopenharmony_ci``` 334e41f4b71Sopenharmony_ci 335e41f4b71Sopenharmony_ci## 应用通过 LocalSocket 进行数据传输 336e41f4b71Sopenharmony_ci 337e41f4b71Sopenharmony_ci1. import 需要的 socket 模块。 338e41f4b71Sopenharmony_ci 339e41f4b71Sopenharmony_ci2. 使用 constructLocalSocketInstance 接口,创建一个 LocalSocket 客户端对象。 340e41f4b71Sopenharmony_ci 341e41f4b71Sopenharmony_ci3. 注册 LocalSocket 的消息(message)事件,以及一些其它事件(可选)。 342e41f4b71Sopenharmony_ci 343e41f4b71Sopenharmony_ci4. 连接到指定的本地套接字文件路径。 344e41f4b71Sopenharmony_ci 345e41f4b71Sopenharmony_ci5. 发送数据。 346e41f4b71Sopenharmony_ci 347e41f4b71Sopenharmony_ci6. Socket 连接使用完毕后,取消事件的注册,并关闭套接字。 348e41f4b71Sopenharmony_ci 349e41f4b71Sopenharmony_ci```ts 350e41f4b71Sopenharmony_ciimport { socket } from '@kit.NetworkKit'; 351e41f4b71Sopenharmony_ci 352e41f4b71Sopenharmony_ci// 创建一个LocalSocket连接,返回一个LocalSocket对象。 353e41f4b71Sopenharmony_cilet client: socket.LocalSocket = socket.constructLocalSocketInstance(); 354e41f4b71Sopenharmony_ciclient.on('message', (value: socket.LocalSocketMessageInfo) => { 355e41f4b71Sopenharmony_ci const uintArray = new Uint8Array(value.message) 356e41f4b71Sopenharmony_ci let messageView = ''; 357e41f4b71Sopenharmony_ci for (let i = 0; i < uintArray.length; i++) { 358e41f4b71Sopenharmony_ci messageView += String.fromCharCode(uintArray[i]); 359e41f4b71Sopenharmony_ci } 360e41f4b71Sopenharmony_ci console.log('total receive: ' + JSON.stringify(value)); 361e41f4b71Sopenharmony_ci console.log('message information: ' + messageView); 362e41f4b71Sopenharmony_ci}); 363e41f4b71Sopenharmony_ciclient.on('connect', () => { 364e41f4b71Sopenharmony_ci console.log("on connect"); 365e41f4b71Sopenharmony_ci}); 366e41f4b71Sopenharmony_ciclient.on('close', () => { 367e41f4b71Sopenharmony_ci console.log("on close"); 368e41f4b71Sopenharmony_ci}); 369e41f4b71Sopenharmony_ci 370e41f4b71Sopenharmony_ci// 传入指定的本地套接字路径,连接服务端。 371e41f4b71Sopenharmony_cilet sandboxPath: string = getContext(this).filesDir + '/testSocket' 372e41f4b71Sopenharmony_cilet localAddress : socket.LocalAddress = { 373e41f4b71Sopenharmony_ci address: sandboxPath 374e41f4b71Sopenharmony_ci} 375e41f4b71Sopenharmony_cilet connectOpt: socket.LocalConnectOptions = { 376e41f4b71Sopenharmony_ci address: localAddress, 377e41f4b71Sopenharmony_ci timeout: 6000 378e41f4b71Sopenharmony_ci} 379e41f4b71Sopenharmony_cilet sendOpt: socket.LocalSendOptions = { 380e41f4b71Sopenharmony_ci data: 'Hello world!' 381e41f4b71Sopenharmony_ci} 382e41f4b71Sopenharmony_ciclient.connect(connectOpt).then(() => { 383e41f4b71Sopenharmony_ci console.log('connect success') 384e41f4b71Sopenharmony_ci client.send(sendOpt).then(() => { 385e41f4b71Sopenharmony_ci console.log('send success') 386e41f4b71Sopenharmony_ci }).catch((err: Object) => { 387e41f4b71Sopenharmony_ci console.log('send failed: ' + JSON.stringify(err)) 388e41f4b71Sopenharmony_ci }) 389e41f4b71Sopenharmony_ci}).catch((err: Object) => { 390e41f4b71Sopenharmony_ci console.log('connect fail: ' + JSON.stringify(err)); 391e41f4b71Sopenharmony_ci}); 392e41f4b71Sopenharmony_ci 393e41f4b71Sopenharmony_ci// 当不需要再连接服务端,需要断开且取消事件的监听时 394e41f4b71Sopenharmony_ciclient.off('message'); 395e41f4b71Sopenharmony_ciclient.off('connect'); 396e41f4b71Sopenharmony_ciclient.off('close'); 397e41f4b71Sopenharmony_ciclient.close().then(() => { 398e41f4b71Sopenharmony_ci console.log('close client success') 399e41f4b71Sopenharmony_ci}).catch((err: Object) => { 400e41f4b71Sopenharmony_ci console.log('close client err: ' + JSON.stringify(err)) 401e41f4b71Sopenharmony_ci}) 402e41f4b71Sopenharmony_ci``` 403e41f4b71Sopenharmony_ci 404e41f4b71Sopenharmony_ci## 应用通过 Local Socket Server 进行数据传输 405e41f4b71Sopenharmony_ci 406e41f4b71Sopenharmony_ci服务端 LocalSocket Server 流程: 407e41f4b71Sopenharmony_ci 408e41f4b71Sopenharmony_ci1. import 需要的 socket 模块。 409e41f4b71Sopenharmony_ci 410e41f4b71Sopenharmony_ci2. 使用 constructLocalSocketServerInstance 接口,创建一个 LocalSocketServer 服务端对象。 411e41f4b71Sopenharmony_ci 412e41f4b71Sopenharmony_ci3. 启动服务,绑定本地套接字路径,创建出本地套接字文件,监听客户端的连接请求。 413e41f4b71Sopenharmony_ci 414e41f4b71Sopenharmony_ci4. 注册 LocalSocket 的客户端连接(connect)事件,以及一些其它事件(可选)。 415e41f4b71Sopenharmony_ci 416e41f4b71Sopenharmony_ci5. 在客户端连接上来时,通过连接事件的回调函数,获取连接会话对象。 417e41f4b71Sopenharmony_ci 418e41f4b71Sopenharmony_ci6. 给会话对象 LocalSocketConnection 注册消息(message)事件,以及一些其它事件(可选)。 419e41f4b71Sopenharmony_ci 420e41f4b71Sopenharmony_ci7. 通过会话对象主动向客户端发送消息。 421e41f4b71Sopenharmony_ci 422e41f4b71Sopenharmony_ci8. 结束与客户端的通信,主动断开与客户端的连接。 423e41f4b71Sopenharmony_ci 424e41f4b71Sopenharmony_ci9. 取消 LocalSocketConnection 和 LocalSocketServer 相关事件的订阅。 425e41f4b71Sopenharmony_ci 426e41f4b71Sopenharmony_ci```ts 427e41f4b71Sopenharmony_ciimport { socket } from '@kit.NetworkKit'; 428e41f4b71Sopenharmony_ci 429e41f4b71Sopenharmony_ci// 创建一个LocalSocketServer连接,返回一个LocalSocketServer对象。 430e41f4b71Sopenharmony_cilet server: socket.LocalSocketServer = socket.constructLocalSocketServerInstance(); 431e41f4b71Sopenharmony_ci// 创建并绑定本地套接字文件testSocket,进行监听 432e41f4b71Sopenharmony_cilet sandboxPath: string = getContext(this).filesDir + '/testSocket' 433e41f4b71Sopenharmony_cilet listenAddr: socket.LocalAddress = { 434e41f4b71Sopenharmony_ci address: sandboxPath 435e41f4b71Sopenharmony_ci} 436e41f4b71Sopenharmony_ciserver.listen(listenAddr).then(() => { 437e41f4b71Sopenharmony_ci console.log("listen success"); 438e41f4b71Sopenharmony_ci}).catch((err: Object) => { 439e41f4b71Sopenharmony_ci console.log("listen fail: " + JSON.stringify(err)); 440e41f4b71Sopenharmony_ci}); 441e41f4b71Sopenharmony_ci 442e41f4b71Sopenharmony_ci// 订阅LocalSocketServer的connect事件 443e41f4b71Sopenharmony_ciserver.on('connect', (connection: socket.LocalSocketConnection) => { 444e41f4b71Sopenharmony_ci // 订阅LocalSocketConnection相关的事件 445e41f4b71Sopenharmony_ci connection.on('error', (err: Object) => { 446e41f4b71Sopenharmony_ci console.log("on error success"); 447e41f4b71Sopenharmony_ci }); 448e41f4b71Sopenharmony_ci connection.on('message', (value: socket.LocalSocketMessageInfo) => { 449e41f4b71Sopenharmony_ci const uintArray = new Uint8Array(value.message); 450e41f4b71Sopenharmony_ci let messageView = ''; 451e41f4b71Sopenharmony_ci for (let i = 0; i < uintArray.length; i++) { 452e41f4b71Sopenharmony_ci messageView += String.fromCharCode(uintArray[i]); 453e41f4b71Sopenharmony_ci } 454e41f4b71Sopenharmony_ci console.log('total: ' + JSON.stringify(value)); 455e41f4b71Sopenharmony_ci console.log('message information: ' + messageView); 456e41f4b71Sopenharmony_ci }); 457e41f4b71Sopenharmony_ci 458e41f4b71Sopenharmony_ci connection.on('error', (err: Object) => { 459e41f4b71Sopenharmony_ci console.log("err:" + JSON.stringify(err)); 460e41f4b71Sopenharmony_ci }) 461e41f4b71Sopenharmony_ci 462e41f4b71Sopenharmony_ci // 向客户端发送数据 463e41f4b71Sopenharmony_ci let sendOpt : socket.LocalSendOptions = { 464e41f4b71Sopenharmony_ci data: 'Hello world!' 465e41f4b71Sopenharmony_ci }; 466e41f4b71Sopenharmony_ci connection.send(sendOpt).then(() => { 467e41f4b71Sopenharmony_ci console.log('send success'); 468e41f4b71Sopenharmony_ci }).catch((err: Object) => { 469e41f4b71Sopenharmony_ci console.log('send failed: ' + JSON.stringify(err)); 470e41f4b71Sopenharmony_ci }) 471e41f4b71Sopenharmony_ci 472e41f4b71Sopenharmony_ci // 关闭与客户端的连接 473e41f4b71Sopenharmony_ci connection.close().then(() => { 474e41f4b71Sopenharmony_ci console.log('close success'); 475e41f4b71Sopenharmony_ci }).catch((err: Object) => { 476e41f4b71Sopenharmony_ci console.log('close failed: ' + JSON.stringify(err)); 477e41f4b71Sopenharmony_ci }); 478e41f4b71Sopenharmony_ci 479e41f4b71Sopenharmony_ci // 取消LocalSocketConnection相关的事件订阅 480e41f4b71Sopenharmony_ci connection.off('message'); 481e41f4b71Sopenharmony_ci connection.off('error'); 482e41f4b71Sopenharmony_ci}); 483e41f4b71Sopenharmony_ci 484e41f4b71Sopenharmony_ci// 取消LocalSocketServer相关的事件订阅 485e41f4b71Sopenharmony_ciserver.off('connect'); 486e41f4b71Sopenharmony_ciserver.off('error'); 487e41f4b71Sopenharmony_ci``` 488e41f4b71Sopenharmony_ci 489e41f4b71Sopenharmony_ci## 应用通过 TLS Socket 进行加密数据传输 490e41f4b71Sopenharmony_ci 491e41f4b71Sopenharmony_ci客户端 TLS Socket 流程: 492e41f4b71Sopenharmony_ci 493e41f4b71Sopenharmony_ci1. import 需要的 socket 模块。 494e41f4b71Sopenharmony_ci 495e41f4b71Sopenharmony_ci2. 绑定服务器 IP 和端口号。 496e41f4b71Sopenharmony_ci 497e41f4b71Sopenharmony_ci3. 双向认证上传客户端 CA 证书及数字证书;单向认证上传客户端 CA 证书。 498e41f4b71Sopenharmony_ci 499e41f4b71Sopenharmony_ci4. 创建一个 TLSSocket 连接,返回一个 TLSSocket 对象。 500e41f4b71Sopenharmony_ci 501e41f4b71Sopenharmony_ci5. (可选)订阅 TLSSocket 相关的订阅事件。 502e41f4b71Sopenharmony_ci 503e41f4b71Sopenharmony_ci6. 发送数据。 504e41f4b71Sopenharmony_ci 505e41f4b71Sopenharmony_ci7. TLSSocket 连接使用完毕后,主动关闭。 506e41f4b71Sopenharmony_ci 507e41f4b71Sopenharmony_ci```ts 508e41f4b71Sopenharmony_ciimport { socket } from '@kit.NetworkKit'; 509e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 510e41f4b71Sopenharmony_ci 511e41f4b71Sopenharmony_ciclass SocketInfo { 512e41f4b71Sopenharmony_ci message: ArrayBuffer = new ArrayBuffer(1); 513e41f4b71Sopenharmony_ci remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo; 514e41f4b71Sopenharmony_ci} 515e41f4b71Sopenharmony_ci// 创建一个(双向认证)TLS Socket连接,返回一个TLS Socket对象。 516e41f4b71Sopenharmony_cilet tlsTwoWay: socket.TLSSocket = socket.constructTLSSocketInstance(); 517e41f4b71Sopenharmony_ci// 订阅TLS Socket相关的订阅事件 518e41f4b71Sopenharmony_citlsTwoWay.on('message', (value: SocketInfo) => { 519e41f4b71Sopenharmony_ci console.log("on message"); 520e41f4b71Sopenharmony_ci let buffer = value.message; 521e41f4b71Sopenharmony_ci let dataView = new DataView(buffer); 522e41f4b71Sopenharmony_ci let str = ""; 523e41f4b71Sopenharmony_ci for (let i = 0; i < dataView.byteLength; ++i) { 524e41f4b71Sopenharmony_ci str += String.fromCharCode(dataView.getUint8(i)); 525e41f4b71Sopenharmony_ci } 526e41f4b71Sopenharmony_ci console.log("on connect received:" + str); 527e41f4b71Sopenharmony_ci}); 528e41f4b71Sopenharmony_citlsTwoWay.on('connect', () => { 529e41f4b71Sopenharmony_ci console.log("on connect"); 530e41f4b71Sopenharmony_ci}); 531e41f4b71Sopenharmony_citlsTwoWay.on('close', () => { 532e41f4b71Sopenharmony_ci console.log("on close"); 533e41f4b71Sopenharmony_ci}); 534e41f4b71Sopenharmony_ci 535e41f4b71Sopenharmony_ci// 绑定本地IP地址和端口。 536e41f4b71Sopenharmony_cilet ipAddress : socket.NetAddress = {} as socket.NetAddress; 537e41f4b71Sopenharmony_ciipAddress.address = "192.168.xxx.xxx"; 538e41f4b71Sopenharmony_ciipAddress.port = 4512; 539e41f4b71Sopenharmony_citlsTwoWay.bind(ipAddress, (err: BusinessError) => { 540e41f4b71Sopenharmony_ci if (err) { 541e41f4b71Sopenharmony_ci console.log('bind fail'); 542e41f4b71Sopenharmony_ci return; 543e41f4b71Sopenharmony_ci } 544e41f4b71Sopenharmony_ci console.log('bind success'); 545e41f4b71Sopenharmony_ci}); 546e41f4b71Sopenharmony_ci 547e41f4b71Sopenharmony_ciipAddress.address = "192.168.xxx.xxx"; 548e41f4b71Sopenharmony_ciipAddress.port = 1234; 549e41f4b71Sopenharmony_ci 550e41f4b71Sopenharmony_cilet tlsSecureOption : socket.TLSSecureOptions = {} as socket.TLSSecureOptions; 551e41f4b71Sopenharmony_citlsSecureOption.key = "xxxx"; 552e41f4b71Sopenharmony_citlsSecureOption.cert = "xxxx"; 553e41f4b71Sopenharmony_citlsSecureOption.ca = ["xxxx"]; 554e41f4b71Sopenharmony_citlsSecureOption.password = "xxxx"; 555e41f4b71Sopenharmony_citlsSecureOption.protocols = [socket.Protocol.TLSv12]; 556e41f4b71Sopenharmony_citlsSecureOption.useRemoteCipherPrefer = true; 557e41f4b71Sopenharmony_citlsSecureOption.signatureAlgorithms = "rsa_pss_rsae_sha256:ECDSA+SHA256"; 558e41f4b71Sopenharmony_citlsSecureOption.cipherSuite = "AES256-SHA256"; 559e41f4b71Sopenharmony_ci 560e41f4b71Sopenharmony_cilet tlsTwoWayConnectOption : socket.TLSConnectOptions = {} as socket.TLSConnectOptions; 561e41f4b71Sopenharmony_citlsSecureOption.key = "xxxx"; 562e41f4b71Sopenharmony_citlsTwoWayConnectOption.address = ipAddress; 563e41f4b71Sopenharmony_citlsTwoWayConnectOption.secureOptions = tlsSecureOption; 564e41f4b71Sopenharmony_citlsTwoWayConnectOption.ALPNProtocols = ["spdy/1", "http/1.1"]; 565e41f4b71Sopenharmony_ci 566e41f4b71Sopenharmony_ci// 建立连接 567e41f4b71Sopenharmony_citlsTwoWay.connect(tlsTwoWayConnectOption).then(() => { 568e41f4b71Sopenharmony_ci console.log("connect successfully"); 569e41f4b71Sopenharmony_ci}).catch((err: BusinessError) => { 570e41f4b71Sopenharmony_ci console.log("connect failed " + JSON.stringify(err)); 571e41f4b71Sopenharmony_ci}); 572e41f4b71Sopenharmony_ci 573e41f4b71Sopenharmony_ci// 连接使用完毕后,主动关闭。取消相关事件的订阅。 574e41f4b71Sopenharmony_citlsTwoWay.close((err: BusinessError) => { 575e41f4b71Sopenharmony_ci if (err) { 576e41f4b71Sopenharmony_ci console.log("close callback error = " + err); 577e41f4b71Sopenharmony_ci } else { 578e41f4b71Sopenharmony_ci console.log("close success"); 579e41f4b71Sopenharmony_ci } 580e41f4b71Sopenharmony_ci tlsTwoWay.off('message'); 581e41f4b71Sopenharmony_ci tlsTwoWay.off('connect'); 582e41f4b71Sopenharmony_ci tlsTwoWay.off('close'); 583e41f4b71Sopenharmony_ci}); 584e41f4b71Sopenharmony_ci 585e41f4b71Sopenharmony_ci// 创建一个(单向认证)TLS Socket连接,返回一个TLS Socket对象。 586e41f4b71Sopenharmony_cilet tlsOneWay: socket.TLSSocket = socket.constructTLSSocketInstance(); // One way authentication 587e41f4b71Sopenharmony_ci 588e41f4b71Sopenharmony_ci// 订阅TLS Socket相关的订阅事件 589e41f4b71Sopenharmony_citlsTwoWay.on('message', (value: SocketInfo) => { 590e41f4b71Sopenharmony_ci console.log("on message"); 591e41f4b71Sopenharmony_ci let buffer = value.message; 592e41f4b71Sopenharmony_ci let dataView = new DataView(buffer); 593e41f4b71Sopenharmony_ci let str = ""; 594e41f4b71Sopenharmony_ci for (let i = 0; i < dataView.byteLength; ++i) { 595e41f4b71Sopenharmony_ci str += String.fromCharCode(dataView.getUint8(i)); 596e41f4b71Sopenharmony_ci } 597e41f4b71Sopenharmony_ci console.log("on connect received:" + str); 598e41f4b71Sopenharmony_ci}); 599e41f4b71Sopenharmony_citlsTwoWay.on('connect', () => { 600e41f4b71Sopenharmony_ci console.log("on connect"); 601e41f4b71Sopenharmony_ci}); 602e41f4b71Sopenharmony_citlsTwoWay.on('close', () => { 603e41f4b71Sopenharmony_ci console.log("on close"); 604e41f4b71Sopenharmony_ci}); 605e41f4b71Sopenharmony_ci 606e41f4b71Sopenharmony_ci// 绑定本地IP地址和端口。 607e41f4b71Sopenharmony_ciipAddress.address = "192.168.xxx.xxx"; 608e41f4b71Sopenharmony_ciipAddress.port = 5445; 609e41f4b71Sopenharmony_citlsOneWay.bind(ipAddress, (err:BusinessError) => { 610e41f4b71Sopenharmony_ci if (err) { 611e41f4b71Sopenharmony_ci console.log('bind fail'); 612e41f4b71Sopenharmony_ci return; 613e41f4b71Sopenharmony_ci } 614e41f4b71Sopenharmony_ci console.log('bind success'); 615e41f4b71Sopenharmony_ci}); 616e41f4b71Sopenharmony_ci 617e41f4b71Sopenharmony_ciipAddress.address = "192.168.xxx.xxx"; 618e41f4b71Sopenharmony_ciipAddress.port = 8789; 619e41f4b71Sopenharmony_cilet tlsOneWaySecureOption : socket.TLSSecureOptions = {} as socket.TLSSecureOptions; 620e41f4b71Sopenharmony_citlsOneWaySecureOption.ca = ["xxxx", "xxxx"]; 621e41f4b71Sopenharmony_citlsOneWaySecureOption.cipherSuite = "AES256-SHA256"; 622e41f4b71Sopenharmony_ci 623e41f4b71Sopenharmony_cilet tlsOneWayConnectOptions: socket.TLSConnectOptions = {} as socket.TLSConnectOptions; 624e41f4b71Sopenharmony_citlsOneWayConnectOptions.address = ipAddress; 625e41f4b71Sopenharmony_citlsOneWayConnectOptions.secureOptions = tlsOneWaySecureOption; 626e41f4b71Sopenharmony_ci 627e41f4b71Sopenharmony_ci// 建立连接 628e41f4b71Sopenharmony_citlsOneWay.connect(tlsOneWayConnectOptions).then(() => { 629e41f4b71Sopenharmony_ci console.log("connect successfully"); 630e41f4b71Sopenharmony_ci}).catch((err: BusinessError) => { 631e41f4b71Sopenharmony_ci console.log("connect failed " + JSON.stringify(err)); 632e41f4b71Sopenharmony_ci}); 633e41f4b71Sopenharmony_ci 634e41f4b71Sopenharmony_ci// 连接使用完毕后,主动关闭。取消相关事件的订阅。 635e41f4b71Sopenharmony_citlsTwoWay.close((err: BusinessError) => { 636e41f4b71Sopenharmony_ci if (err) { 637e41f4b71Sopenharmony_ci console.log("close callback error = " + err); 638e41f4b71Sopenharmony_ci } else { 639e41f4b71Sopenharmony_ci console.log("close success"); 640e41f4b71Sopenharmony_ci } 641e41f4b71Sopenharmony_ci tlsTwoWay.off('message'); 642e41f4b71Sopenharmony_ci tlsTwoWay.off('connect'); 643e41f4b71Sopenharmony_ci tlsTwoWay.off('close'); 644e41f4b71Sopenharmony_ci}); 645e41f4b71Sopenharmony_ci``` 646e41f4b71Sopenharmony_ci 647e41f4b71Sopenharmony_ci## 应用通过将 TCP Socket 升级为 TLS Socket 进行加密数据传输 648e41f4b71Sopenharmony_ci 649e41f4b71Sopenharmony_ci客户端 TCP Socket 升级为 TLS Socket 流程: 650e41f4b71Sopenharmony_ci 651e41f4b71Sopenharmony_ci1. import 需要的 socket 模块。 652e41f4b71Sopenharmony_ci 653e41f4b71Sopenharmony_ci2. 参考[应用 TCP/UDP 协议进行通信](#应用-tcpudp-协议进行通信),创建一个 TCPSocket 连接。 654e41f4b71Sopenharmony_ci 655e41f4b71Sopenharmony_ci3. 确保 TCPSocket 已连接后,使用该 TCPSocket 对象创建 TLSSocket 连接,返回一个 TLSSocket 对象。 656e41f4b71Sopenharmony_ci 657e41f4b71Sopenharmony_ci4. 双向认证上传客户端 CA 证书及数字证书;单向认证上传客户端 CA 证书。 658e41f4b71Sopenharmony_ci 659e41f4b71Sopenharmony_ci5. (可选)订阅 TLSSocket 相关的订阅事件。 660e41f4b71Sopenharmony_ci 661e41f4b71Sopenharmony_ci6. 发送数据。 662e41f4b71Sopenharmony_ci 663e41f4b71Sopenharmony_ci7. TLSSocket 连接使用完毕后,主动关闭。 664e41f4b71Sopenharmony_ci 665e41f4b71Sopenharmony_ci```ts 666e41f4b71Sopenharmony_ciimport { socket } from '@kit.NetworkKit'; 667e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 668e41f4b71Sopenharmony_ci 669e41f4b71Sopenharmony_ciclass SocketInfo { 670e41f4b71Sopenharmony_ci message: ArrayBuffer = new ArrayBuffer(1); 671e41f4b71Sopenharmony_ci remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo; 672e41f4b71Sopenharmony_ci} 673e41f4b71Sopenharmony_ci 674e41f4b71Sopenharmony_ci// 创建一个TCPSocket连接,返回一个TCPSocket对象。 675e41f4b71Sopenharmony_cilet tcp: socket.TCPSocket = socket.constructTCPSocketInstance(); 676e41f4b71Sopenharmony_citcp.on('message', (value: SocketInfo) => { 677e41f4b71Sopenharmony_ci console.log("on message"); 678e41f4b71Sopenharmony_ci let buffer = value.message; 679e41f4b71Sopenharmony_ci let dataView = new DataView(buffer); 680e41f4b71Sopenharmony_ci let str = ""; 681e41f4b71Sopenharmony_ci for (let i = 0; i < dataView.byteLength; ++i) { 682e41f4b71Sopenharmony_ci str += String.fromCharCode(dataView.getUint8(i)); 683e41f4b71Sopenharmony_ci } 684e41f4b71Sopenharmony_ci console.log("on connect received:" + str); 685e41f4b71Sopenharmony_ci}); 686e41f4b71Sopenharmony_citcp.on('connect', () => { 687e41f4b71Sopenharmony_ci console.log("on connect"); 688e41f4b71Sopenharmony_ci}); 689e41f4b71Sopenharmony_ci 690e41f4b71Sopenharmony_ci// 绑定本地IP地址和端口。 691e41f4b71Sopenharmony_cilet ipAddress: socket.NetAddress = {} as socket.NetAddress; 692e41f4b71Sopenharmony_ciipAddress.address = "192.168.xxx.xxx"; 693e41f4b71Sopenharmony_ciipAddress.port = 1234; 694e41f4b71Sopenharmony_citcp.bind(ipAddress, (err: BusinessError) => { 695e41f4b71Sopenharmony_ci if (err) { 696e41f4b71Sopenharmony_ci console.log('bind fail'); 697e41f4b71Sopenharmony_ci return; 698e41f4b71Sopenharmony_ci } 699e41f4b71Sopenharmony_ci console.log('bind success'); 700e41f4b71Sopenharmony_ci 701e41f4b71Sopenharmony_ci // 连接到指定的IP地址和端口。 702e41f4b71Sopenharmony_ci ipAddress.address = "192.168.xxx.xxx"; 703e41f4b71Sopenharmony_ci ipAddress.port = 443; 704e41f4b71Sopenharmony_ci 705e41f4b71Sopenharmony_ci let tcpConnect: socket.TCPConnectOptions = {} as socket.TCPConnectOptions; 706e41f4b71Sopenharmony_ci tcpConnect.address = ipAddress; 707e41f4b71Sopenharmony_ci tcpConnect.timeout = 6000; 708e41f4b71Sopenharmony_ci 709e41f4b71Sopenharmony_ci tcp.connect(tcpConnect, (err: BusinessError) => { 710e41f4b71Sopenharmony_ci if (err) { 711e41f4b71Sopenharmony_ci console.log('connect fail'); 712e41f4b71Sopenharmony_ci return; 713e41f4b71Sopenharmony_ci } 714e41f4b71Sopenharmony_ci console.log('connect success'); 715e41f4b71Sopenharmony_ci 716e41f4b71Sopenharmony_ci // 确保TCPSocket已连接后,将其升级为TLSSocket连接。 717e41f4b71Sopenharmony_ci let tlsTwoWay: socket.TLSSocket = socket.constructTLSSocketInstance(tcp); 718e41f4b71Sopenharmony_ci // 订阅TLSSocket相关的订阅事件。 719e41f4b71Sopenharmony_ci tlsTwoWay.on('message', (value: SocketInfo) => { 720e41f4b71Sopenharmony_ci console.log("tls on message"); 721e41f4b71Sopenharmony_ci let buffer = value.message; 722e41f4b71Sopenharmony_ci let dataView = new DataView(buffer); 723e41f4b71Sopenharmony_ci let str = ""; 724e41f4b71Sopenharmony_ci for (let i = 0; i < dataView.byteLength; ++i) { 725e41f4b71Sopenharmony_ci str += String.fromCharCode(dataView.getUint8(i)); 726e41f4b71Sopenharmony_ci } 727e41f4b71Sopenharmony_ci console.log("tls on connect received:" + str); 728e41f4b71Sopenharmony_ci }); 729e41f4b71Sopenharmony_ci tlsTwoWay.on('connect', () => { 730e41f4b71Sopenharmony_ci console.log("tls on connect"); 731e41f4b71Sopenharmony_ci }); 732e41f4b71Sopenharmony_ci tlsTwoWay.on('close', () => { 733e41f4b71Sopenharmony_ci console.log("tls on close"); 734e41f4b71Sopenharmony_ci }); 735e41f4b71Sopenharmony_ci 736e41f4b71Sopenharmony_ci // 配置TLSSocket目的地址、证书等信息。 737e41f4b71Sopenharmony_ci ipAddress.address = "192.168.xxx.xxx"; 738e41f4b71Sopenharmony_ci ipAddress.port = 1234; 739e41f4b71Sopenharmony_ci 740e41f4b71Sopenharmony_ci let tlsSecureOption: socket.TLSSecureOptions = {} as socket.TLSSecureOptions; 741e41f4b71Sopenharmony_ci tlsSecureOption.key = "xxxx"; 742e41f4b71Sopenharmony_ci tlsSecureOption.cert = "xxxx"; 743e41f4b71Sopenharmony_ci tlsSecureOption.ca = ["xxxx"]; 744e41f4b71Sopenharmony_ci tlsSecureOption.password = "xxxx"; 745e41f4b71Sopenharmony_ci tlsSecureOption.protocols = [socket.Protocol.TLSv12]; 746e41f4b71Sopenharmony_ci tlsSecureOption.useRemoteCipherPrefer = true; 747e41f4b71Sopenharmony_ci tlsSecureOption.signatureAlgorithms = "rsa_pss_rsae_sha256:ECDSA+SHA256"; 748e41f4b71Sopenharmony_ci tlsSecureOption.cipherSuite = "AES256-SHA256"; 749e41f4b71Sopenharmony_ci 750e41f4b71Sopenharmony_ci let tlsTwoWayConnectOption: socket.TLSConnectOptions = {} as socket.TLSConnectOptions; 751e41f4b71Sopenharmony_ci tlsSecureOption.key = "xxxx"; 752e41f4b71Sopenharmony_ci tlsTwoWayConnectOption.address = ipAddress; 753e41f4b71Sopenharmony_ci tlsTwoWayConnectOption.secureOptions = tlsSecureOption; 754e41f4b71Sopenharmony_ci tlsTwoWayConnectOption.ALPNProtocols = ["spdy/1", "http/1.1"]; 755e41f4b71Sopenharmony_ci 756e41f4b71Sopenharmony_ci // 建立TLSSocket连接 757e41f4b71Sopenharmony_ci tlsTwoWay.connect(tlsTwoWayConnectOption, () => { 758e41f4b71Sopenharmony_ci console.log("tls connect success"); 759e41f4b71Sopenharmony_ci 760e41f4b71Sopenharmony_ci // 连接使用完毕后,主动关闭。取消相关事件的订阅。 761e41f4b71Sopenharmony_ci tlsTwoWay.close((err: BusinessError) => { 762e41f4b71Sopenharmony_ci if (err) { 763e41f4b71Sopenharmony_ci console.log("tls close callback error = " + err); 764e41f4b71Sopenharmony_ci } else { 765e41f4b71Sopenharmony_ci console.log("tls close success"); 766e41f4b71Sopenharmony_ci } 767e41f4b71Sopenharmony_ci tlsTwoWay.off('message'); 768e41f4b71Sopenharmony_ci tlsTwoWay.off('connect'); 769e41f4b71Sopenharmony_ci tlsTwoWay.off('close'); 770e41f4b71Sopenharmony_ci }); 771e41f4b71Sopenharmony_ci }); 772e41f4b71Sopenharmony_ci }); 773e41f4b71Sopenharmony_ci}); 774e41f4b71Sopenharmony_ci``` 775e41f4b71Sopenharmony_ci 776e41f4b71Sopenharmony_ci## 应用通过 TLS Socket Server 进行加密数据传输 777e41f4b71Sopenharmony_ci 778e41f4b71Sopenharmony_ci服务端 TLS Socket Server 流程: 779e41f4b71Sopenharmony_ci 780e41f4b71Sopenharmony_ci1. import 需要的 socket 模块。 781e41f4b71Sopenharmony_ci 782e41f4b71Sopenharmony_ci2. 启动服务,绑定 IP 和端口号,监听客户端连接,创建并初始化 TLS 会话,加载证书密钥并验证。 783e41f4b71Sopenharmony_ci 784e41f4b71Sopenharmony_ci3. 订阅 TLSSocketServer 的连接事件。 785e41f4b71Sopenharmony_ci 786e41f4b71Sopenharmony_ci4. 收到客户端连接,通过回调得到 TLSSocketConnection 对象。 787e41f4b71Sopenharmony_ci 788e41f4b71Sopenharmony_ci5. 订阅 TLSSocketConnection 相关的事件。 789e41f4b71Sopenharmony_ci 790e41f4b71Sopenharmony_ci6. 发送数据。 791e41f4b71Sopenharmony_ci 792e41f4b71Sopenharmony_ci7. TLSSocketConnection 连接使用完毕后,断开连接。 793e41f4b71Sopenharmony_ci 794e41f4b71Sopenharmony_ci8. 取消订阅 TLSSocketConnection 以及 TLSSocketServer 的相关事件。 795e41f4b71Sopenharmony_ci 796e41f4b71Sopenharmony_ci```ts 797e41f4b71Sopenharmony_ciimport { socket } from '@kit.NetworkKit'; 798e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 799e41f4b71Sopenharmony_ci 800e41f4b71Sopenharmony_cilet tlsServer: socket.TLSSocketServer = socket.constructTLSSocketServerInstance(); 801e41f4b71Sopenharmony_ci 802e41f4b71Sopenharmony_cilet netAddress: socket.NetAddress = { 803e41f4b71Sopenharmony_ci address: '192.168.xx.xxx', 804e41f4b71Sopenharmony_ci port: 8080 805e41f4b71Sopenharmony_ci} 806e41f4b71Sopenharmony_ci 807e41f4b71Sopenharmony_cilet tlsSecureOptions: socket.TLSSecureOptions = { 808e41f4b71Sopenharmony_ci key: "xxxx", 809e41f4b71Sopenharmony_ci cert: "xxxx", 810e41f4b71Sopenharmony_ci ca: ["xxxx"], 811e41f4b71Sopenharmony_ci password: "xxxx", 812e41f4b71Sopenharmony_ci protocols: socket.Protocol.TLSv12, 813e41f4b71Sopenharmony_ci useRemoteCipherPrefer: true, 814e41f4b71Sopenharmony_ci signatureAlgorithms: "rsa_pss_rsae_sha256:ECDSA+SHA256", 815e41f4b71Sopenharmony_ci cipherSuite: "AES256-SHA256" 816e41f4b71Sopenharmony_ci} 817e41f4b71Sopenharmony_ci 818e41f4b71Sopenharmony_cilet tlsConnectOptions: socket.TLSConnectOptions = { 819e41f4b71Sopenharmony_ci address: netAddress, 820e41f4b71Sopenharmony_ci secureOptions: tlsSecureOptions, 821e41f4b71Sopenharmony_ci ALPNProtocols: ["spdy/1", "http/1.1"] 822e41f4b71Sopenharmony_ci} 823e41f4b71Sopenharmony_ci 824e41f4b71Sopenharmony_citlsServer.listen(tlsConnectOptions).then(() => { 825e41f4b71Sopenharmony_ci console.log("listen callback success"); 826e41f4b71Sopenharmony_ci}).catch((err: BusinessError) => { 827e41f4b71Sopenharmony_ci console.log("failed" + err); 828e41f4b71Sopenharmony_ci}); 829e41f4b71Sopenharmony_ci 830e41f4b71Sopenharmony_ciclass SocketInfo { 831e41f4b71Sopenharmony_ci message: ArrayBuffer = new ArrayBuffer(1); 832e41f4b71Sopenharmony_ci remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo; 833e41f4b71Sopenharmony_ci} 834e41f4b71Sopenharmony_cilet callback = (value: SocketInfo) => { 835e41f4b71Sopenharmony_ci let messageView = ''; 836e41f4b71Sopenharmony_ci for (let i: number = 0; i < value.message.byteLength; i++) { 837e41f4b71Sopenharmony_ci let uint8Array = new Uint8Array(value.message) 838e41f4b71Sopenharmony_ci let messages = uint8Array[i] 839e41f4b71Sopenharmony_ci let message = String.fromCharCode(messages); 840e41f4b71Sopenharmony_ci messageView += message; 841e41f4b71Sopenharmony_ci } 842e41f4b71Sopenharmony_ci console.log('on message message: ' + JSON.stringify(messageView)); 843e41f4b71Sopenharmony_ci console.log('remoteInfo: ' + JSON.stringify(value.remoteInfo)); 844e41f4b71Sopenharmony_ci} 845e41f4b71Sopenharmony_citlsServer.on('connect', (client: socket.TLSSocketConnection) => { 846e41f4b71Sopenharmony_ci client.on('message', callback); 847e41f4b71Sopenharmony_ci 848e41f4b71Sopenharmony_ci // 发送数据 849e41f4b71Sopenharmony_ci client.send('Hello, client!').then(() => { 850e41f4b71Sopenharmony_ci console.log('send success'); 851e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 852e41f4b71Sopenharmony_ci console.log('send fail'); 853e41f4b71Sopenharmony_ci }); 854e41f4b71Sopenharmony_ci 855e41f4b71Sopenharmony_ci // 断开连接 856e41f4b71Sopenharmony_ci client.close().then(() => { 857e41f4b71Sopenharmony_ci console.log('close success'); 858e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 859e41f4b71Sopenharmony_ci console.log('close fail'); 860e41f4b71Sopenharmony_ci }); 861e41f4b71Sopenharmony_ci 862e41f4b71Sopenharmony_ci // 可以指定传入on中的callback取消一个订阅,也可以不指定callback清空所有订阅。 863e41f4b71Sopenharmony_ci client.off('message', callback); 864e41f4b71Sopenharmony_ci client.off('message'); 865e41f4b71Sopenharmony_ci}); 866e41f4b71Sopenharmony_ci 867e41f4b71Sopenharmony_ci// 取消订阅tlsServer的相关事件 868e41f4b71Sopenharmony_citlsServer.off('connect'); 869e41f4b71Sopenharmony_ci``` 870e41f4b71Sopenharmony_ci 871e41f4b71Sopenharmony_ci## 相关实例 872e41f4b71Sopenharmony_ci 873e41f4b71Sopenharmony_ci针对 Socket 连接开发,有以下相关实例可供参考: 874e41f4b71Sopenharmony_ci 875e41f4b71Sopenharmony_ci- [网络管理-Socket 连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Socket) 876