• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Socket连接
2
3## 简介
4
5Socket连接主要是通过Socket进行数据传输,支持TCP/UDP/TLS协议。
6
7## 基本概念
8
9- Socket:套接字,就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。
10- TCP:传输控制协议(Transmission Control Protocol)。是一种面向连接的、可靠的、基于字节流的传输层通信协议。
11- UDP:用户数据报协议协议(User Datagram Protocol)。是一个简单的面向消息的传输层,不需要连接。
12- TLS:安全传输层协议(Transport Layer Security)。用于在两个通信应用程序之间提供保密性和数据完整性。
13
14## 场景介绍
15
16应用通过Socket进行数据传输,支持TCP/UDP/TLS协议。主要场景有:
17
18- 应用通过TCP/UDP Socket进行数据传输
19- 应用通过TLS Socket进行加密数据传输
20
21## 接口说明
22
23完整的JS API说明以及实例代码请参考:[Socket连接](../reference/apis/js-apis-socket.md)。
24
25Socket连接主要由socket模块提供。具体接口说明如下表。
26
27| 接口名 | 功能描述 |
28| -------- | -------- |
29| constructUDPSocketInstance() | 创建一个UDPSocket对象。 |
30| constructTCPSocketInstance() | 创建一个TCPSocket对象。 |
31| bind() | 绑定IP地址和端口。 |
32| send() | 发送数据。 |
33| close() | 关闭连接。 |
34| getState() | 获取Socket状态。 |
35| connect() | 连接到指定的IP地址和端口(仅TCP支持) |
36| getRemoteAddress() | 获取对端Socket地址(仅TCP支持,需要先调用connect方法) |
37| on(type: 'message') | 订阅Socket连接的接收消息事件。 |
38| off(type: 'message') | 取消订阅Socket连接的接收消息事件。 |
39| on(type: 'close') | 订阅Socket连接的关闭事件。 |
40| off(type: 'close') | 取消订阅Socket连接的关闭事件。 |
41| on(type: 'error') | 订阅Socket连接的Error事件。 |
42| off(type: 'error') | 取消订阅Socket连接的Error事件。 |
43| on(type: 'listening') | 订阅UDPSocket连接的数据包消息事件(仅UDP支持)。 |
44| off(type: 'listening') | 取消订阅UDPSocket连接的数据包消息事件(仅UDP支持)。 |
45| on(type: 'connect') | 订阅TCPSocket的连接事件(仅TCP支持)。 |
46| off(type: 'connect') | 取消订阅TCPSocket的连接事件(仅TCP支持)。 |
47
48TLS Socket连接主要由tls_socket模块提供。具体接口说明如下表。
49
50| 接口名 | 功能描述 |
51| -------- | -------- |
52| constructTLSSocketInstance() | 创建一个TLSSocket对象。 |
53| bind() | 绑定IP地址和端口号。 |
54| close(type: 'error') | 关闭连接。 |
55| connect() | 连接到指定的IP地址和端口。 |
56| getCertificate() | 返回表示本地证书的对象。 |
57| getCipherSuite() | 返回包含协商的密码套件信息的列表。 |
58| getProtocol() | 返回包含当前连接协商的SSL/TLS协议版本的字符串。 |
59| getRemoteAddress() | 获取TLSSocket连接的对端地址。 |
60| getRemoteCertificate() | 返回表示对等证书的对象。 |
61| getSignatureAlgorithms() | 在服务器和客户端之间共享的签名算法列表,按优先级降序排列。 |
62| getState() | 获取TLSSocket连接的状态。 |
63| off(type: 'close') | 取消订阅TLSSocket连接的关闭事件。 |
64| off(type: 'error') | 取消订阅TLSSocket连接的Error事件。 |
65| off(type: 'message') | 取消订阅TLSSocket连接的接收消息事件。 |
66| on(type: 'close') | 订阅TLSSocket连接的关闭事件。 |
67| on(type: 'error') | 订阅TLSSocket连接的Error事件。 |
68| on(type: 'message') | 订阅TLSSocket连接的接收消息事件。 |
69| send() | 发送数据。 |
70| setExtraOptions() | 设置TLSSocket连接的其他属性。 |
71
72## 应用TCP/UDP协议进行通信
73
74UDP与TCP流程大体类似,下面以TCP为例:
75
761. import需要的socket模块。
77
782. 创建一个TCPSocket连接,返回一个TCPSocket对象。
79
803. (可选)订阅TCPSocket相关的订阅事件。
81
824. 绑定IP地址和端口,端口可以指定或由系统随机分配。
83
845. 连接到指定的IP地址和端口。
85
866. 发送数据。
87
887. Socket连接使用完毕后,主动关闭。
89
90   ```js
91   import socket from '@ohos.net.socket'
92
93   // 创建一个TCPSocket连接,返回一个TCPSocket对象。
94   let tcp = socket.constructTCPSocketInstance();
95
96   // 订阅TCPSocket相关的订阅事件
97   tcp.on('message', value => {
98       console.log("on message")
99       let buffer = value.message
100       let dataView = new DataView(buffer)
101       let str = ""
102       for (let i = 0;i < dataView.byteLength; ++i) {
103           str += String.fromCharCode(dataView.getUint8(i))
104       }
105       console.log("on connect received:" + str)
106   });
107   tcp.on('connect', () => {
108       console.log("on connect")
109   });
110   tcp.on('close', () => {
111       console.log("on close")
112   });
113
114   // 绑定本地IP地址和端口。
115   let bindAddress = {
116       address: '192.168.xx.xx',
117       port: 1234, // 绑定端口,如1234
118       family: 1
119   };
120   tcp.bind(bindAddress, err => {
121       if (err) {
122           console.log('bind fail');
123           return;
124       }
125       console.log('bind success');
126
127       // 连接到指定的IP地址和端口。
128       let connectAddress = {
129           address: '192.168.xx.xx',
130           port: 5678, // 连接端口,如5678
131           family: 1
132       };
133       tcp.connect({
134           address: connectAddress, timeout: 6000
135       }, err => {
136           if (err) {
137               console.log('connect fail');
138               return;
139           }
140           console.log('connect success');
141
142           // 发送数据
143           tcp.send({
144               data: 'Hello, server!'
145           }, err => {
146               if (err) {
147                   console.log('send fail');
148                   return;
149               }
150               console.log('send success');
151           })
152       });
153   });
154
155   // 连接使用完毕后,主动关闭。取消相关事件的订阅。
156   setTimeout(() => {
157       tcp.close((err) => {
158           console.log('close socket.')
159       });
160       tcp.off('message');
161       tcp.off('connect');
162       tcp.off('close');
163   }, 30 * 1000);
164   ```
165
166## 应用通过TLS Socket进行加密数据传输
167
168### 开发步骤
169
170客户端TLS Socket流程:
171
1721. import需要的socket模块。
173
1742. 绑定服务器IP和端口号。
175
1763. 双向认证上传客户端CA证书及数字证书;单向认证上传客户端CA证书。
177
1784. 创建一个TLSSocket连接,返回一个TLSSocket对象。
179
1805. (可选)订阅TLSSocket相关的订阅事件。
181
1826. 发送数据。
183
1847. TLSSocket连接使用完毕后,主动关闭。
185
186```js
187   import socket from '@ohos.net.socket'
188
189   // 创建一个(双向认证)TLS Socket连接,返回一个TLS Socket对象。
190   let tlsTwoWay = socket.constructTLSSocketInstance();
191
192   // 订阅TLS Socket相关的订阅事件
193   tlsTwoWay.on('message', value => {
194       console.log("on message")
195       let buffer = value.message
196       let dataView = new DataView(buffer)
197       let str = ""
198       for (let i = 0; i < dataView.byteLength; ++i) {
199           str += String.fromCharCode(dataView.getUint8(i))
200       }
201       console.log("on connect received:" + str)
202   });
203   tlsTwoWay.on('connect', () => {
204       console.log("on connect")
205   });
206   tlsTwoWay.on('close', () => {
207       console.log("on close")
208   });
209
210   // 绑定本地IP地址和端口。
211   tlsTwoWay.bind({address: '192.168.xxx.xxx', port: xxxx, family: 1}, err => {
212       if (err) {
213           console.log('bind fail');
214           return;
215       }
216       console.log('bind success');
217   });
218
219   // 设置通信过程中使用参数
220   let options = {
221       ALPNProtocols: ["spdy/1", "http/1.1"],
222
223       // 连接到指定的IP地址和端口。
224       address: {
225           address: "192.168.xx.xxx",
226           port: xxxx, // 端口
227           family: 1,
228       },
229
230       // 设置用于通信过程中完成校验的参数。
231       secureOptions: {
232           key: "xxxx",                            // 密钥
233           cert: "xxxx",                           // 数字证书
234           ca: ["xxxx"],                           // CA证书
235           passwd: "xxxx",                         // 生成密钥时的密码
236           protocols: [socket.Protocol.TLSv12],    // 通信协议
237           useRemoteCipherPrefer: true,            // 是否优先使用对端密码套件
238           signatureAlgorithms: "rsa_pss_rsae_sha256:ECDSA+SHA256",    // 签名算法
239           cipherSuite: "AES256-SHA256",           // 密码套件
240       },
241   };
242
243   // 建立连接
244   tlsTwoWay.connect(options, (err, data) => {
245       console.error(err);
246       console.log(data);
247   });
248
249   // 连接使用完毕后,主动关闭。取消相关事件的订阅。
250   tlsTwoWay.close((err) => {
251       if (err) {
252           console.log("close callback error = " + err);
253       } else {
254           console.log("close success");
255       }
256       tlsTwoWay.off('message');
257       tlsTwoWay.off('connect');
258       tlsTwoWay.off('close');
259   });
260
261   // 创建一个(单向认证)TLS Socket连接,返回一个TLS Socket对象。
262   let tlsOneWay = socket.constructTLSSocketInstance(); // One way authentication
263
264   // 订阅TLS Socket相关的订阅事件
265   tlsTwoWay.on('message', value => {
266       console.log("on message")
267       let buffer = value.message
268       let dataView = new DataView(buffer)
269       let str = ""
270       for (let i = 0;i < dataView.byteLength; ++i) {
271           str += String.fromCharCode(dataView.getUint8(i))
272       }
273       console.log("on connect received:" + str)
274   });
275   tlsTwoWay.on('connect', () => {
276       console.log("on connect")
277   });
278   tlsTwoWay.on('close', () => {
279       console.log("on close")
280   });
281
282   // 绑定本地IP地址和端口。
283   tlsOneWay.bind({address: '192.168.xxx.xxx', port: xxxx, family: 1}, err => {
284       if (err) {
285           console.log('bind fail');
286           return;
287       }
288       console.log('bind success');
289   });
290
291   // 设置通信过程中使用参数
292   let oneWayOptions = {
293       address: {
294           address: "192.168.xxx.xxx",
295           port: xxxx,
296           family: 1,
297       },
298       secureOptions: {
299           ca: ["xxxx","xxxx"],            // CA证书
300           cipherSuite: "AES256-SHA256",   // 密码套件
301       },
302   };
303
304   // 建立连接
305   tlsOneWay.connect(oneWayOptions, (err, data) => {
306       console.error(err);
307       console.log(data);
308   });
309
310   // 连接使用完毕后,主动关闭。取消相关事件的订阅。
311   tlsTwoWay.close((err) => {
312       if (err) {
313           console.log("close callback error = " + err);
314       } else {
315           console.log("close success");
316       }
317       tlsTwoWay.off('message');
318       tlsTwoWay.off('connect');
319       tlsTwoWay.off('close');
320   });
321```
322
323## 相关实例
324
325针对Socket连接开发,有以下相关实例可供参考:
326- [`Socket`:Socket 连接(ArkTS)(API9)](https://gitee.com/openharmony/applications_app_samples/tree/OpenHarmony-3.2-Release/Network/Socket)
327- [使用UDP实现与服务端通信(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/UdpDemoOH)
328- [使用TCP实现与服务端通信(ArkTS)(API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/TcpSocketDemo)
329