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