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