• 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
91import socket from '@ohos.net.socket'
92
93// 创建一个TCPSocket连接,返回一个TCPSocket对象。
94let tcp = socket.constructTCPSocketInstance();
95
96// 订阅TCPSocket相关的订阅事件
97tcp.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});
107tcp.on('connect', () => {
108  console.log("on connect")
109});
110tcp.on('close', () => {
111  console.log("on close")
112});
113
114// 绑定IP地址和端口。
115let bindAddress = {
116  address: '192.168.xx.xx',
117  port: 1234, // 绑定端口,如1234
118  family: 1
119};
120tcp.bind(bindAddress, err => {
121  if (err) {
122    console.log('bind fail');
123    return;
124  }
125  console.log('bind success');
126  // 连接到指定的IP地址和端口。
127  let connectAddress = {
128    address: '192.168.xx.xx',
129    port: 5678, // 连接端口,如5678
130    family: 1
131  };
132  tcp.connect({
133    address: connectAddress, timeout: 6000
134  }, err => {
135    if (err) {
136      console.log('connect fail');
137      return;
138    }
139    console.log('connect success');
140    // 发送数据
141    tcp.send({
142      data: 'Hello, server!'
143    }, err => {
144      if (err) {
145        console.log('send fail');
146        return;
147      }
148      console.log('send success');
149    })
150  });
151});
152// 连接使用完毕后,主动关闭。取消相关事件的订阅。
153setTimeout(() => {
154  tcp.close((err) => {
155    console.log('close socket.')
156  });
157  tcp.off('message');
158  tcp.off('connect');
159  tcp.off('close');
160}, 30 * 1000);
161```
162
163## 应用通过TLS Socket进行加密数据传输
164
165### 开发步骤
166
167客户端TLS Socket流程:
168
1691. import需要的socket模块。
170
1712. 绑定服务器IP和端口号。
172
1733. 双向认证上传客户端CA证书及数字证书;单向认证上传客户端CA证书。
174
1754. 创建一个TLSSocket连接,返回一个TLSSocket对象。
176
1775. (可选)订阅TLSSocket相关的订阅事件。
178
1796. 发送数据。
180
1817. TLSSocket连接使用完毕后,主动关闭。
182
183```js
184// 创建一个(双向认证)TLS Socket连接,返回一个TLS Socket对象。
185let tlsTwoWay = socket.constructTLSSocketInstance();
186
187// 订阅TLS Socket相关的订阅事件
188tlsTwoWay.on('message', value => {
189  console.log("on message")
190  let buffer = value.message
191  let dataView = new DataView(buffer)
192  let str = ""
193  for (let i = 0; i < dataView.byteLength; ++i) {
194    str += String.fromCharCode(dataView.getUint8(i))
195  }
196  console.log("on connect received:" + str)
197});
198tlsTwoWay.on('connect', () => {
199  console.log("on connect")
200});
201tlsTwoWay.on('close', () => {
202  console.log("on close")
203});
204
205// 绑定本地IP地址和端口。
206tlsTwoWay.bind({ address: '192.168.xxx.xxx', port: xxxx, family: 1 }, err => {
207  if (err) {
208    console.log('bind fail');
209    return;
210  }
211  console.log('bind success');
212});
213
214// 设置通信过程中使用参数
215let options = {
216  ALPNProtocols: ["spdy/1", "http/1.1"],
217
218  // 连接到指定的IP地址和端口。
219  address: {
220    address: "192.168.xx.xxx",
221    port: xxxx, // 端口
222    family: 1,
223  },
224
225  // 设置用于通信过程中完成校验的参数。
226  secureOptions: {
227    key: "xxxx",                            // 密钥
228    cert: "xxxx",                           // 数字证书
229    ca: ["xxxx"],                           // CA证书
230    passwd: "xxxx",                         // 生成密钥时的密码
231    protocols: [socket.Protocol.TLSv12],    // 通信协议
232    useRemoteCipherPrefer: true,            // 是否优先使用对端密码套件
233    signatureAlgorithms: "rsa_pss_rsae_sha256:ECDSA+SHA256",    // 签名算法
234    cipherSuite: "AES256-SHA256",           // 密码套件
235  },
236};
237
238// 建立连接
239tlsTwoWay.connect(options, (err, data) => {
240  console.error(err);
241  console.log(data);
242});
243
244// 连接使用完毕后,主动关闭。取消相关事件的订阅。
245tlsTwoWay.close((err) => {
246  if (err) {
247    console.log("close callback error = " + err);
248  } else {
249    console.log("close success");
250  }
251  tlsTwoWay.off('message');
252  tlsTwoWay.off('connect');
253  tlsTwoWay.off('close');
254});
255
256// 创建一个(单向认证)TLS Socket连接,返回一个TLS Socket对象。
257let tlsOneWay = socket.constructTLSSocketInstance(); // One way authentication
258
259// 订阅TLS Socket相关的订阅事件
260tlsTwoWay.on('message', value => {
261  console.log("on message")
262  let buffer = value.message
263  let dataView = new DataView(buffer)
264  let str = ""
265  for (let i = 0; i < dataView.byteLength; ++i) {
266    str += String.fromCharCode(dataView.getUint8(i))
267  }
268  console.log("on connect received:" + str)
269});
270tlsTwoWay.on('connect', () => {
271  console.log("on connect")
272});
273tlsTwoWay.on('close', () => {
274  console.log("on close")
275});
276
277// 绑定本地IP地址和端口。
278tlsOneWay.bind({ address: '192.168.xxx.xxx', port: xxxx, family: 1 }, err => {
279  if (err) {
280    console.log('bind fail');
281    return;
282  }
283  console.log('bind success');
284});
285
286// 设置通信过程中使用参数
287let oneWayOptions = {
288  address: {
289    address: "192.168.xxx.xxx",
290    port: xxxx,
291    family: 1,
292  },
293  secureOptions: {
294    ca: ["xxxx", "xxxx"],            // CA证书
295    cipherSuite: "AES256-SHA256",   // 密码套件
296  },
297};
298
299// 建立连接
300tlsOneWay.connect(oneWayOptions, (err, data) => {
301  console.error(err);
302  console.log(data);
303});
304
305// 连接使用完毕后,主动关闭。取消相关事件的订阅。
306tlsTwoWay.close((err) => {
307  if (err) {
308    console.log("close callback error = " + err);
309  } else {
310    console.log("close success");
311  }
312  tlsTwoWay.off('message');
313  tlsTwoWay.off('connect');
314  tlsTwoWay.off('close');
315});
316```
317
318