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