鸿蒙网络管理模块02——Socket

news2024/10/2 22:34:55

如果你也对鸿蒙开发感兴趣,加入“Harmony自习室”吧!扫描下方名片,关注公众号,公众号更新更快,同时也有更多学习资料和技术讨论群。

1、概述

Socket 连接主要是通过 Socket 进行数据传输,支持 TCP/UDP/Multicast/TLS 协议。主要涉及到的场景有:

  • 应用通过 TCP/UDP Socket进行数据传输

  • 应用通过 TCP Socket Server 进行数据传输

  • 应用通过 Multicast Socket 进行数据传输

  • 应用通过 Local Socket进行数据传输

  • 应用通过 Local Socket Server 进行数据传输

  • 应用通过 TLS Socket 进行加密数据传输

  • 应用通过 TLS Socket Server 进行加密数据传输

细心的朋友可能发现,上述的场景基本都是成对出现,形式例如:xxx Socket 与之匹配的是 xxx Socket Server。正如命名形式,xxx Socket是客户端侧、xxx Socket Server是服务端侧。

举一个APP实际场景:用户两个设备需要传输大量数据时(例如手机转移助手),必然会有一个是客户端侧接受数据,一个是服务端侧发送数据。所以出现有上述客户端和服务端的区别。千万不要狭义的理解为Server是后端服务器。

上述涉及到的一些基本名词介绍如下:

  • Socket:套接字,就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。

  • TCP:传输控制协议(Transmission Control Protocol)。是一种面向连接的、可靠的、基于字节流的传输层通信协议。

  • UDP:用户数据报协议(User Datagram Protocol)。是一个简单的面向消息的传输层,不需要连接。

  • Multicast:多播,基于UDP的一种通信模式,用于实现组内所有设备之间广播形式的通信。

  • LocalSocket:本地套接字,IPC(Inter-Process Communication)进程间通信的一种,实现设备内进程之间相互通信,无需网络。

  • TLS:安全传输层协议(Transport Layer Security)。用于在两个通信应用程序之间提供保密性和数据完整性。

socket 模块(Socket功能)提供的具体接口说明如下表:

图片

tls_socket 模块(提供TLS Socket加密数据传输功能)提供。具体接口说明如下表

图片

下面针对上述的7种主要的通讯场景做简要介绍:

2、TCP/UDP协议传输数据

UDP 与 TCP 流程大体类似,下面以 TCP 为例:

  1. import 需要的 socket 模块。

  2. 创建一个 TCPSocket 连接,返回一个 TCPSocket 对象。

  3. (可选)订阅 TCPSocket 相关的订阅事件。

  4. 绑定 IP 地址和端口,端口可以指定或由系统随机分配。

  5. 连接到指定的 IP 地址和端口。

  6. 发送数据。

  7. Socket 连接使用完毕后,主动关闭。

import { socket } from '@kit.NetworkKit';import { BusinessError } from '@kit.BasicServicesKit';class SocketInfo {  message: ArrayBuffer = new ArrayBuffer(1);  remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo;}// 创建一个TCPSocket连接,返回一个TCPSocket对象。let tcp: socket.TCPSocket = socket.constructTCPSocketInstance();tcp.on('message', (value: SocketInfo) => {  console.log("on message");  let buffer = value.message;  let dataView = new DataView(buffer);  let str = "";  for (let i = 0; i < dataView.byteLength; ++i) {    str += String.fromCharCode(dataView.getUint8(i));  }  console.log("on connect received:" + str);});tcp.on('connect', () => {  console.log("on connect");});tcp.on('close', () => {  console.log("on close");});// 绑定本地IP地址和端口。let ipAddress : socket.NetAddress = {} as socket.NetAddress;ipAddress.address = "192.168.xxx.xxx";ipAddress.port = 1234;tcp.bind(ipAddress, (err: BusinessError) => {  if (err) {    console.log('bind fail');    return;  }  console.log('bind success');  // 连接到指定的IP地址和端口。  ipAddress.address = "192.168.xxx.xxx";  ipAddress.port = 5678;  let tcpConnect : socket.TCPConnectOptions = {} as socket.TCPConnectOptions;  tcpConnect.address = ipAddress;  tcpConnect.timeout = 6000;  tcp.connect(tcpConnect).then(() => {    console.log('connect success');    let tcpSendOptions: socket.TCPSendOptions = {      data: 'Hello, server!'    }    tcp.send(tcpSendOptions).then(() => {      console.log('send success');    }).catch((err: BusinessError) => {      console.log('send fail');    });  }).catch((err: BusinessError) => {    console.log('connect fail');  });});// 连接使用完毕后,主动关闭。取消相关事件的订阅。setTimeout(() => {  tcp.close().then(() => {    console.log('close success');  }).catch((err: BusinessError) => {    console.log('close fail');  });  tcp.off('message');  tcp.off('connect');  tcp.off('close');}, 30 * 1000);

3、TCP Socket Server传输数据

服务端 TCP Socket 流程:

  1. import 需要的 socket 模块。

  2. 创建一个 TCPSocketServer 连接,返回一个 TCPSocketServer 对象。

  3. 绑定本地 IP 地址和端口,监听并接受与此套接字建立的客户端 TCPSocket 连接。

  4. 订阅 TCPSocketServer 的 connect 事件,用于监听客户端的连接状态。

  5. 客户端与服务端建立连接后,返回一个 TCPSocketConnection 对象,用于与客户端通信。

  6. 订阅 TCPSocketConnection 相关的事件,通过 TCPSocketConnection 向客户端发送数据。

  7. 主动关闭与客户端的连接。

  8. 取消 TCPSocketConnection 和 TCPSocketServer 相关事件的订阅。

import { socket } from '@kit.NetworkKit';import { BusinessError } from '@kit.BasicServicesKit';// 创建一个TCPSocketServer连接,返回一个TCPSocketServer对象。let tcpServer: socket.TCPSocketServer = socket.constructTCPSocketServerInstance();// 绑定本地IP地址和端口,进行监听let ipAddress : socket.NetAddress = {} as socket.NetAddress;ipAddress.address = "192.168.xxx.xxx";ipAddress.port = 4651;tcpServer.listen(ipAddress).then(() => {  console.log('listen success');}).catch((err: BusinessError) => {  console.log('listen fail');});class SocketInfo {  message: ArrayBuffer = new ArrayBuffer(1);  remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo;}// 订阅TCPSocketServer的connect事件tcpServer.on("connect", (client: socket.TCPSocketConnection) => {  // 订阅TCPSocketConnection相关的事件  client.on("close", () => {    console.log("on close success");  });  client.on("message", (value: SocketInfo) => {    let buffer = value.message;    let dataView = new DataView(buffer);    let str = "";    for (let i = 0; i < dataView.byteLength; ++i) {      str += String.fromCharCode(dataView.getUint8(i));    }    console.log("received message--:" + str);    console.log("received address--:" + value.remoteInfo.address);    console.log("received family--:" + value.remoteInfo.family);    console.log("received port--:" + value.remoteInfo.port);    console.log("received size--:" + value.remoteInfo.size);  });  // 向客户端发送数据  let tcpSendOptions : socket.TCPSendOptions = {} as socket.TCPSendOptions;  tcpSendOptions.data = 'Hello, client!';  client.send(tcpSendOptions).then(() => {    console.log('send success');  }).catch((err: Object) => {    console.error('send fail: ' + JSON.stringify(err));  });  // 关闭与客户端的连接  client.close().then(() => {    console.log('close success');  }).catch((err: BusinessError) => {    console.log('close fail');  });  // 取消TCPSocketConnection相关的事件订阅  setTimeout(() => {    client.off("message");    client.off("close");  }, 10 * 1000);});// 取消TCPSocketServer相关的事件订阅setTimeout(() => {  tcpServer.off("connect");}, 30 * 1000);

4、Multicast Socket传输数据

  1. mport 需要的 socket 模块。

  2. 创建 multicastSocket 多播对象。

  3. 指定多播 IP 与端口,加入多播组。

  4. 开启消息 message 监听。

  5. 发送数据,数据以广播的形式传输,同一多播组中已经开启消息 message 监听的多播对象都会接收到数据。

  6. 关闭 message 消息的监听。

  7. 退出多播组

import { socket } from '@kit.NetworkKit';// 创建Multicast对象let multicast: socket.MulticastSocket = socket.constructMulticastSocketInstance();let addr : socket.NetAddress = {  address: '239.255.0.1',  port: 32123,  family: 1}// 加入多播组multicast.addMembership(addr).then(() => {  console.log('addMembership success');}).catch((err: Object) => {  console.log('addMembership fail');});// 开启监听消息数据,将接收到的ArrayBuffer类型数据转换为Stringclass SocketInfo {  message: ArrayBuffer = new ArrayBuffer(1);  remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo;}multicast.on('message', (data: SocketInfo) => {  console.info('接收的数据: ' + JSON.stringify(data))  const uintArray = new Uint8Array(data.message)  let str = ''  for (let i = 0; i < uintArray.length; ++i) {    str += String.fromCharCode(uintArray[i])  }  console.info(str)})// 发送数据multicast.send({ data:'Hello12345', address: addr }).then(() => {  console.log('send success');}).catch((err: Object) => {  console.log('send fail, ' + JSON.stringify(err));});// 关闭消息的监听multicast.off('message')// 退出多播组multicast.dropMembership(addr).then(() => {  console.log('drop membership success');}).catch((err: Object) => {  console.log('drop membership fail');});

5、LocalSocket传输数据

  1. import 需要的 socket 模块。

  2. 使用 constructLocalSocketInstance 接口,创建一个 LocalSocket 客户端对象。

  3. 注册 LocalSocket 的消息(message)事件,以及一些其它事件(可选)。

  4. 连接到指定的本地套接字文件路径。

  5. 发送数据。

  6. Socket 连接使用完毕后,取消事件的注册,并关闭套接字。

import { socket } from '@kit.NetworkKit';// 创建一个LocalSocket连接,返回一个LocalSocket对象。let client: socket.LocalSocket = socket.constructLocalSocketInstance();client.on('message', (value: socket.LocalSocketMessageInfo) => {  const uintArray = new Uint8Array(value.message)  let messageView = '';  for (let i = 0; i < uintArray.length; i++) {    messageView += String.fromCharCode(uintArray[i]);  }  console.log('total receive: ' + JSON.stringify(value));  console.log('message information: ' + messageView);});client.on('connect', () => {  console.log("on connect");});client.on('close', () => {  console.log("on close");});// 传入指定的本地套接字路径,连接服务端。let sandboxPath: string = getContext(this).filesDir + '/testSocket'let localAddress : socket.LocalAddress = {  address: sandboxPath}let connectOpt: socket.LocalConnectOptions = {  address: localAddress,  timeout: 6000}let sendOpt: socket.LocalSendOptions = {  data: 'Hello world!'}client.connect(connectOpt).then(() => {  console.log('connect success')  client.send(sendOpt).then(() => {  console.log('send success')  }).catch((err: Object) => {    console.log('send failed: ' + JSON.stringify(err))  })}).catch((err: Object) => {  console.log('connect fail: ' + JSON.stringify(err));});// 当不需要再连接服务端,需要断开且取消事件的监听时client.off('message');client.off('connect');client.off('close');client.close().then(() => {  console.log('close client success')}).catch((err: Object) => {  console.log('close client err: ' + JSON.stringify(err))})

6、Local Socket Server传输数据

服务端 LocalSocket Server 流程:

  1. import 需要的 socket 模块。

  2. 使用 constructLocalSocketServerInstance 接口,创建一个 LocalSocketServer 服务端对象。

  3. 启动服务,绑定本地套接字路径,创建出本地套接字文件,监听客户端的连接请求。

  4. 注册 LocalSocket 的客户端连接(connect)事件,以及一些其它事件(可选)。

  5. 在客户端连接上来时,通过连接事件的回调函数,获取连接会话对象。

  6. 给会话对象 LocalSocketConnection 注册消息(message)事件,以及一些其它事件(可选)。

  7. 通过会话对象主动向客户端发送消息。

  8. 结束与客户端的通信,主动断开与客户端的连接。

  9. 取消 LocalSocketConnection 和 LocalSocketServer 相关事件的订阅。

import { socket } from '@kit.NetworkKit';// 创建一个LocalSocketServer连接,返回一个LocalSocketServer对象。let server: socket.LocalSocketServer = socket.constructLocalSocketServerInstance();// 创建并绑定本地套接字文件testSocket,进行监听let sandboxPath: string = getContext(this).filesDir + '/testSocket'let listenAddr: socket.LocalAddress = {  address: sandboxPath}server.listen(listenAddr).then(() => {  console.log("listen success");}).catch((err: Object) => {  console.log("listen fail: " + JSON.stringify(err));});// 订阅LocalSocketServer的connect事件server.on('connect', (connection: socket.LocalSocketConnection) => {  // 订阅LocalSocketConnection相关的事件  connection.on('error', (err: Object) => {    console.log("on error success");  });  connection.on('message', (value: socket.LocalSocketMessageInfo) => {    const uintArray = new Uint8Array(value.message);    let messageView = '';    for (let i = 0; i < uintArray.length; i++) {      messageView += String.fromCharCode(uintArray[i]);    }    console.log('total: ' + JSON.stringify(value));    console.log('message information: ' + messageView);  });  connection.on('error', (err: Object) => {    console.log("err:" + JSON.stringify(err));  })  // 向客户端发送数据  let sendOpt : socket.LocalSendOptions = {    data: 'Hello world!'  };  connection.send(sendOpt).then(() => {    console.log('send success');  }).catch((err: Object) => {    console.log('send failed: ' + JSON.stringify(err));  })  // 关闭与客户端的连接  connection.close().then(() => {    console.log('close success');  }).catch((err: Object) => {    console.log('close failed: ' + JSON.stringify(err));  });  // 取消LocalSocketConnection相关的事件订阅  connection.off('message');  connection.off('error');});// 取消LocalSocketServer相关的事件订阅server.off('connect');server.off('error');

7、TLS Socket加密传输数据

客户端 TLS Socket 流程:

  1. import 需要的 socket 模块。

  2. 绑定服务器 IP 和端口号。

  3. 双向认证上传客户端 CA 证书及数字证书;单向认证上传客户端 CA 证书。

  4. 创建一个 TLSSocket 连接,返回一个 TLSSocket 对象。

  5. (可选)订阅 TLSSocket 相关的订阅事件。

  6. 发送数据。

  7. TLSSocket 连接使用完毕后,主动关闭。

import { socket } from '@kit.NetworkKit';import { BusinessError } from '@kit.BasicServicesKit';class SocketInfo {  message: ArrayBuffer = new ArrayBuffer(1);  remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo;}// 创建一个(双向认证)TLS Socket连接,返回一个TLS Socket对象。let tlsTwoWay: socket.TLSSocket = socket.constructTLSSocketInstance();// 订阅TLS Socket相关的订阅事件tlsTwoWay.on('message', (value: SocketInfo) => {  console.log("on message");  let buffer = value.message;  let dataView = new DataView(buffer);  let str = "";  for (let i = 0; i < dataView.byteLength; ++i) {    str += String.fromCharCode(dataView.getUint8(i));  }  console.log("on connect received:" + str);});tlsTwoWay.on('connect', () => {  console.log("on connect");});tlsTwoWay.on('close', () => {  console.log("on close");});// 绑定本地IP地址和端口。let ipAddress : socket.NetAddress = {} as socket.NetAddress;ipAddress.address = "192.168.xxx.xxx";ipAddress.port = 4512;tlsTwoWay.bind(ipAddress, (err: BusinessError) => {  if (err) {    console.log('bind fail');    return;  }  console.log('bind success');});ipAddress.address = "192.168.xxx.xxx";ipAddress.port = 1234;let tlsSecureOption : socket.TLSSecureOptions = {} as socket.TLSSecureOptions;tlsSecureOption.key = "xxxx";tlsSecureOption.cert = "xxxx";tlsSecureOption.ca = ["xxxx"];tlsSecureOption.password = "xxxx";tlsSecureOption.protocols = [socket.Protocol.TLSv12];tlsSecureOption.useRemoteCipherPrefer = true;tlsSecureOption.signatureAlgorithms = "rsa_pss_rsae_sha256:ECDSA+SHA256";tlsSecureOption.cipherSuite = "AES256-SHA256";let tlsTwoWayConnectOption : socket.TLSConnectOptions = {} as socket.TLSConnectOptions;tlsSecureOption.key = "xxxx";tlsTwoWayConnectOption.address = ipAddress;tlsTwoWayConnectOption.secureOptions = tlsSecureOption;tlsTwoWayConnectOption.ALPNProtocols = ["spdy/1", "http/1.1"];// 建立连接tlsTwoWay.connect(tlsTwoWayConnectOption).then(() => {  console.log("connect successfully");}).catch((err: BusinessError) => {  console.log("connect failed " + JSON.stringify(err));});// 连接使用完毕后,主动关闭。取消相关事件的订阅。tlsTwoWay.close((err: BusinessError) => {  if (err) {    console.log("close callback error = " + err);  } else {    console.log("close success");  }  tlsTwoWay.off('message');  tlsTwoWay.off('connect');  tlsTwoWay.off('close');});// 创建一个(单向认证)TLS Socket连接,返回一个TLS Socket对象。let tlsOneWay: socket.TLSSocket = socket.constructTLSSocketInstance(); // One way authentication// 订阅TLS Socket相关的订阅事件tlsTwoWay.on('message', (value: SocketInfo) => {  console.log("on message");  let buffer = value.message;  let dataView = new DataView(buffer);  let str = "";  for (let i = 0; i < dataView.byteLength; ++i) {    str += String.fromCharCode(dataView.getUint8(i));  }  console.log("on connect received:" + str);});tlsTwoWay.on('connect', () => {  console.log("on connect");});tlsTwoWay.on('close', () => {  console.log("on close");});// 绑定本地IP地址和端口。ipAddress.address = "192.168.xxx.xxx";ipAddress.port = 5445;tlsOneWay.bind(ipAddress, (err:BusinessError) => {  if (err) {    console.log('bind fail');    return;  }  console.log('bind success');});ipAddress.address = "192.168.xxx.xxx";ipAddress.port = 8789;let tlsOneWaySecureOption : socket.TLSSecureOptions = {} as socket.TLSSecureOptions;tlsOneWaySecureOption.ca = ["xxxx", "xxxx"];tlsOneWaySecureOption.cipherSuite = "AES256-SHA256";let tlsOneWayConnectOptions: socket.TLSConnectOptions = {} as socket.TLSConnectOptions;tlsOneWayConnectOptions.address = ipAddress;tlsOneWayConnectOptions.secureOptions = tlsOneWaySecureOption;// 建立连接tlsOneWay.connect(tlsOneWayConnectOptions).then(() => {  console.log("connect successfully");}).catch((err: BusinessError) => {  console.log("connect failed " + JSON.stringify(err));});// 连接使用完毕后,主动关闭。取消相关事件的订阅。tlsTwoWay.close((err: BusinessError) => {  if (err) {    console.log("close callback error = " + err);  } else {    console.log("close success");  }  tlsTwoWay.off('message');  tlsTwoWay.off('connect');  tlsTwoWay.off('close');});

8、TCP Socket升级为TLS Socket加密数据传输

客户端 TCP Socket 升级为 TLS Socket 流程:

  1. import 需要的 socket 模块。

  2. 创建一个 TCPSocket 连接(创建方式参考上文第二节:【2、TCP/UDP协议传输数据】 )。

  3. 确保 TCPSocket 已连接后,使用该 TCPSocket 对象创建 TLSSocket 连接,返回一个 TLSSocket 对象。

  4. 双向认证上传客户端 CA 证书及数字证书;单向认证上传客户端 CA 证书。

  5. (可选)订阅 TLSSocket 相关的订阅事件。

  6. 发送数据。

  7. TLSSocket 连接使用完毕后,主动关闭。

import { socket } from '@kit.NetworkKit';import { BusinessError } from '@kit.BasicServicesKit';class SocketInfo {  message: ArrayBuffer = new ArrayBuffer(1);  remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo;}// 创建一个TCPSocket连接,返回一个TCPSocket对象。let tcp: socket.TCPSocket = socket.constructTCPSocketInstance();tcp.on('message', (value: SocketInfo) => {  console.log("on message");  let buffer = value.message;  let dataView = new DataView(buffer);  let str = "";  for (let i = 0; i < dataView.byteLength; ++i) {    str += String.fromCharCode(dataView.getUint8(i));  }  console.log("on connect received:" + str);});tcp.on('connect', () => {  console.log("on connect");});// 绑定本地IP地址和端口。let ipAddress : socket.NetAddress = {} as socket.NetAddress;ipAddress.address = "192.168.xxx.xxx";ipAddress.port = 1234;tcp.bind(ipAddress, (err: BusinessError) => {  if (err) {    console.log('bind fail');    return;  }  console.log('bind success');  // 连接到指定的IP地址和端口。  ipAddress.address = "192.168.xxx.xxx";  ipAddress.port = 443;  let tcpConnect : socket.TCPConnectOptions = {} as socket.TCPConnectOptions;  tcpConnect.address = ipAddress;  tcpConnect.timeout = 6000;  tcp.connect(tcpConnect, (err: BusinessError) => {  if (err) {    console.log('connect fail');    return;  }  console.log('connect success');  // 确保TCPSocket已连接后,将其升级为TLSSocket连接。  let tlsTwoWay: socket.TLSSocket = socket.constructTLSSocketInstance(tcp);  // 订阅TLSSocket相关的订阅事件。  tlsTwoWay.on('message', (value: SocketInfo) => {    console.log("tls on message");    let buffer = value.message;    let dataView = new DataView(buffer);    let str = "";    for (let i = 0; i < dataView.byteLength; ++i) {      str += String.fromCharCode(dataView.getUint8(i));    }    console.log("tls on connect received:" + str);  });  tlsTwoWay.on('connect', () => {    console.log("tls on connect");  });  tlsTwoWay.on('close', () => {    console.log("tls on close");  });  // 配置TLSSocket目的地址、证书等信息。  ipAddress.address = "192.168.xxx.xxx";  ipAddress.port = 1234;  let tlsSecureOption : socket.TLSSecureOptions = {} as socket.TLSSecureOptions;  tlsSecureOption.key = "xxxx";  tlsSecureOption.cert = "xxxx";  tlsSecureOption.ca = ["xxxx"];  tlsSecureOption.password = "xxxx";  tlsSecureOption.protocols = [socket.Protocol.TLSv12];  tlsSecureOption.useRemoteCipherPrefer = true;  tlsSecureOption.signatureAlgorithms = "rsa_pss_rsae_sha256:ECDSA+SHA256";  tlsSecureOption.cipherSuite = "AES256-SHA256";  let tlsTwoWayConnectOption : socket.TLSConnectOptions = {} as socket.TLSConnectOptions;  tlsSecureOption.key = "xxxx";  tlsTwoWayConnectOption.address = ipAddress;  tlsTwoWayConnectOption.secureOptions = tlsSecureOption;  tlsTwoWayConnectOption.ALPNProtocols = ["spdy/1", "http/1.1"];  // 建立TLSSocket连接  tlsTwoWay.connect(tlsTwoWayConnectOption, () => {    console.log("tls connect success");    // 连接使用完毕后,主动关闭。取消相关事件的订阅。    tlsTwoWay.close((err: BusinessError) => {      if (err) {        console.log("tls close callback error = " + err);      } else {        console.log("tls close success");      }      tlsTwoWay.off('message');      tlsTwoWay.off('connect');      tlsTwoWay.off('close');    });  });});

9、TLS Socket Server传输数据

服务端 TLS Socket Server 流程:

  1. import 需要的 socket 模块。

  2. 启动服务,绑定 IP 和端口号,监听客户端连接,创建并初始化 TLS 会话,加载证书密钥并验证。

  3. 订阅 TLSSocketServer 的连接事件。

  4. 收到客户端连接,通过回调得到 TLSSocketConnection 对象。

  5. 订阅 TLSSocketConnection 相关的事件。

  6. 发送数据。

  7. TLSSocketConnection 连接使用完毕后,断开连接。

  8. 取消订阅 TLSSocketConnection 以及 TLSSocketServer 的相关事件。

import { socket } from '@kit.NetworkKit';import { BusinessError } from '@kit.BasicServicesKit';let tlsServer: socket.TLSSocketServer = socket.constructTLSSocketServerInstance();let netAddress: socket.NetAddress = {  address: '192.168.xx.xxx',  port: 8080}let tlsSecureOptions: socket.TLSSecureOptions = {  key: "xxxx",  cert: "xxxx",  ca: ["xxxx"],  password: "xxxx",  protocols: socket.Protocol.TLSv12,  useRemoteCipherPrefer: true,  signatureAlgorithms: "rsa_pss_rsae_sha256:ECDSA+SHA256",  cipherSuite: "AES256-SHA256"}let tlsConnectOptions: socket.TLSConnectOptions = {  address: netAddress,  secureOptions: tlsSecureOptions,  ALPNProtocols: ["spdy/1", "http/1.1"]}tlsServer.listen(tlsConnectOptions).then(() => {  console.log("listen callback success");}).catch((err: BusinessError) => {  console.log("failed" + err);});class SocketInfo {  message: ArrayBuffer = new ArrayBuffer(1);  remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo;}let callback = (value: SocketInfo) => {  let messageView = '';  for (let i: number = 0; i < value.message.byteLength; i++) {    let uint8Array = new Uint8Array(value.message)    let messages = uint8Array[i]    let message = String.fromCharCode(messages);    messageView += message;  }  console.log('on message message: ' + JSON.stringify(messageView));  console.log('remoteInfo: ' + JSON.stringify(value.remoteInfo));}tlsServer.on('connect', (client: socket.TLSSocketConnection) => {  client.on('message', callback);  // 发送数据  client.send('Hello, client!').then(() => {    console.log('send success');  }).catch((err: BusinessError) => {    console.log('send fail');  });  // 断开连接  client.close().then(() => {    console.log('close success');  }).catch((err: BusinessError) => {    console.log('close fail');  });  // 可以指定传入on中的callback取消一个订阅,也可以不指定callback清空所有订阅。  client.off('message', callback);  client.off('message');});// 取消订阅tlsServer的相关事件tlsServer.off('connect');

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2185152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis篇(面试题 - 连环16炮)(持续更新迭代)

目录 &#xff08;第一炮&#xff09;一、Redis&#xff1f;常用数据结构&#xff1f; 1. 项目里面到了Redis&#xff0c;为什么选用Redis&#xff1f; 2. Redis 是什么&#xff1f; 3. Redis和关系型数据库的本质区别有哪些&#xff1f; 4. Redis 的线程模型了解吗&#x…

探索未来:掌握python-can库,开启AI通信新纪元

文章目录 **探索未来&#xff1a;掌握python-can库&#xff0c;开启AI通信新纪元**背景介绍**python-can**库简介安装指南函数使用示例应用场景常见问题及解决方案总结 探索未来&#xff1a;掌握python-can库&#xff0c;开启AI通信新纪元 背景介绍 在人工智能和物联网的飞速…

[Go语言快速上手]函数和包

目录 一、Go中的函数 函数声明 多个返回值 可变参数 匿名函数 值传递和地址传递 函数执行顺序&#xff08;init函数&#xff09; 二、Go中的包 基本语法 主要包&#xff08;main package&#xff09; 导入其他包 包的作用域 包的使用 包名别名 小结 一、Go中的函…

重生之我们在ES顶端相遇第 18 章 - Script 使用(进阶)

文章目录 0. 前言1. 基本使用2. 读请求中访问文档字段2.1 遍历 List2.2 判断对象存不存在2.3 判断值是否为空2.4 总结 3. 写请求中访问文档字段3.1 数字相加3.2 字符串相加3.3 将字符串转为数组 0. 前言 在前面部分&#xff0c;我们介绍了 ES 的基本使用和要掌握的基础性读写原…

TypeScript 算法手册【快速排序】

文章目录 1. 快速排序简介1.1 快速排序定义1.2 快速排序特点 2. 快速排序步骤过程拆解2.1 选择基准元素2.2 划分数组2.3 递归排序 3. 快速排序的优化3.1 三数取中法选择基准3.2 插入排序与快速排序结合案例代码和动态图 4. 快速排序的优点5. 快速排序的缺点总结 【 已更新完 Ty…

二分查找算法专题(1)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 目录 二分查找算法的介绍 704. 二分查找 34. 在排序数组中查找元素的第一个和 最后一个位置 35. 搜索插入位置 69. x的平…

10-指针和多维数组

多维数组&#xff0c;本质上是数组的数组&#xff1a; 一、多维数组&#xff1a; int B[2][3] int(*P)[3] B;Print B //400 Print *B; //400 Print B[0] //400 Print &B[0][0] // 400B[i][j] *(B[i]j) *(*(Bi)j); int C[3][2][2] int(*p)[2][2] C; Print C //800 Prin…

大数据开发--1.1大数据概论

目录 一.大数据的概念 什么是大数据&#xff1f; 二. 大数据的特点 三. 大数据应用场景 四. 大数据分析业务步骤 大数据分析的业务流程&#xff1a; 五.大数据职业规划 职业方向 岗位技术要求 六. 大数据学习路线 一.大数据的概念 什么是大数据&#xff1f; 数据 世界…

【北京迅为】《STM32MP157开发板嵌入式开发指南》- 第十六章 Linux 第一个程序 HelloWorld

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

LC记录二:丑数专题,一文秒解丑数3题

文章目录 263.丑数1264.丑数21201.丑数3 263.丑数1 https://leetcode.cn/problems/ugly-number/description/ 简单题&#xff0c;丑数只包含质因子2、3、5。所以直接使用 n 循环 除 2 3 5最后判断结果是否等于1即可。 代码&#xff1a; class Solution {public boolean isUg…

01_SQLite

文章目录 ** SQLite 存储各类和数据类型 **** SQLite 五种亲缘类型** SQLite 创建数据表删除数据表插入数据信息从数据表中获取数据&#xff0c;以结果表的形式返回数据&#xff08;结果集&#xff09;updatedistinctorder bygroup byhaving触发器删除一个触发器&#xff08;tr…

计网问答大题(期末复习)

计网总结笔记 概述 互联网的 2 个重要基本特点&#xff1a;连通性&#xff0c;资源共享 从互联网的工作方式上看&#xff0c;可以划分为两大块&#xff1a; •边缘部分&#xff1a; 由所有连接在互联网上的主机组成&#xff0c;由用户直接使用&#xff0c;用来进行通信&…

并查集【数据结构与算法】【C语言版-笔记】

目录 一、需求分析二、并查集三、代码实现3.1 Find函数3.2 Union函数3.3 优化13.4 终极优化2---压缩策略 一、需求分析 假设有n个互不相交的集合 ◼问题1&#xff1a;给定某个集合中的一个元素&#xff0c;查找该元素属于哪个集合&#xff1f; ◼问题2&#xff1a;如何合并两个…

建筑业挂靠行为的防范建议

在建筑行业中&#xff0c;挂靠行为的普遍存在给许多企业带来了法律风险和信誉风险。为了防范这些风险&#xff0c;企业需要采取一系列有效的措施。 一、加强资质管理 企业应当通过合法途径获取和提升自身的资质等级&#xff0c;避免因资质不足而产生挂靠的需求。加强资质管理是…

【半导体物理基础】第1章 半导体中的电子状态和能带,晶格结构,有效质量

目录 1.1 半导体晶格结构和结合性质 固体的种类 典型晶体 元素半导体 几种晶胞结构 晶向指数与晶面 半导体的晶体结构 金刚石结构 金刚石结构的结晶学原胞 硅、锗相关参数 硅、锗相关参数计算 闪锌矿结构 纤锌矿结构 氯化钠型结构 1.2 半导体中的电子状态和能带…

Study-Oracle-10-ORALCE19C-RAC集群搭建

一路走来,所有遇到的人,帮助过我的、伤害过我的都是朋友,没有一个是敌人。 ORACLE --RAC 搭建理念:准备工作要仔细,每个参数及配置都到仔细核对。环境准备完成后,剩下的就是图像化操作,没啥难度,所以图形化操作偷懒不续写了。 一、硬件信息及配套软件 1、硬件设置 RAC…

客厅落地台灯怎么摆放?五款客厅落地台灯款式分享

客厅落地台灯怎么摆放&#xff1f;客厅落地台灯是提升光线环境在室内光线质量的关键设备。但如果不慎购买到低质量的客厅落地台灯&#xff0c;可能会导致光线效果不佳&#xff0c;进而影响视力健康。因此&#xff0c;挑选一个可靠的品牌至关重要。那么&#xff0c;客厅落地台灯…

ubuntu 18.04 cuda 11.01 gpgpu-sim 裸机编译

1&#xff0c;环境 ubuntu 18.04 x86_64 cuda 11.01 gpgpu-sim master commit 90ec3399763d7c8512cfe7dc193473086c38ca38 2&#xff0c;预备环境 一个比较新的 ubuntu 18.04&#xff0c;为了迎合 cuda 11.01 的版本需求 安装如下软件&#xff1a; sudo apt-get instal…

Thinkphp/Laravel基于vue的的出版社书籍阅读管理系统

目录 技术栈和环境说明具体实现截图设计思路关键技术课题的重点和难点&#xff1a;框架介绍数据访问方式PHP核心代码部分展示代码目录结构解析系统测试详细视频演示源码获取 技术栈和环境说明 采用PHP语言开发&#xff0c;开发环境为phpstudy 开发工具notepad并使用MYSQL数据库…

netty之NettyClient半包粘包处理、编码解码处理、收发数据方式

前言 Netty开发中&#xff0c;客户端与服务端需要保持同样的&#xff1b;半包粘包处理&#xff0c;编码解码处理、收发数据方式&#xff0c;这样才能保证数据通信正常。在前面NettyServer的章节中我们也同样处理了&#xff1b;半包粘包、编码解码等&#xff0c;为此在本章节我们…