【中秋國慶不斷更】HarmonyOS網路管理開發—Socket連線

HarmonyOS開發者社群發表於2023-10-04

簡介

Socket連線主要是透過Socket進行資料傳輸,支援TCP/UDP/TLS協議。

基本概念

●  Socket:套接字,就是對網路中不同主機上的應用程式之間進行雙向通訊的端點的抽象。

●  TCP:傳輸控制協議(Transmission Control Protocol)。是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議。

●  UDP:使用者資料包協議協議(User Datagram Protocol)。是一個簡單的面向訊息的傳輸層,不需要連線。

●  TLS:安全傳輸層協議(Transport Layer Security)。用於在兩個通訊應用程式之間提供保密性和資料完整性。

場景介紹

應用透過Socket進行資料傳輸,支援TCP/UDP/TLS協議。主要場景有:

●  應用透過TCP/UDP Socket進行資料傳輸

●  應用透過TLS Socket進行加密資料傳輸

介面說明

完整的JS API說明以及例項程式碼請參考: Socket連線

Socket連線主要由socket模組提供。具體介面說明如下表。

介面名

功能描述

constructUDPSocketInstance()

建立一個UDPSocket物件。

constructTCPSocketInstance()

建立一個TCPSocket物件。

bind()

繫結IP地址和埠。

send()

傳送資料。

close()

關閉連線。

getState()

獲取Socket狀態。

connect()

連線到指定的IP地址和埠(僅TCP支援)

getRemoteAddress()

獲取對端Socket地址(僅TCP支援,需要先呼叫connect方法)

on(type: 'message')

訂閱Socket連線的接收訊息事件。

off(type: 'message')

取消訂閱Socket連線的接收訊息事件。

on(type: 'close')

訂閱Socket連線的關閉事件。

off(type: 'close')

取消訂閱Socket連線的關閉事件。

on(type: 'error')

訂閱Socket連線的Error事件。

off(type: 'error')

取消訂閱Socket連線的Error事件。

on(type: 'listening')

訂閱UDPSocket連線的資料包訊息事件(僅UDP支援)。

off(type: 'listening')

取消訂閱UDPSocket連線的資料包訊息事件(僅UDP支援)。

on(type: 'connect')

訂閱TCPSocket的連線事件(僅TCP支援)。

off(type: 'connect')

取消訂閱TCPSocket的連線事件(僅TCP支援)。

TLS Socket連線主要由tls_socket模組提供。具體介面說明如下表。

介面名

功能描述

constructTLSSocketInstance()

建立一個TLSSocket物件。

bind()

繫結IP地址和埠號。

close(type: 'error')

關閉連線。

connect()

連線到指定的IP地址和埠。

getCertificate()

返回表示本地證書的物件。

getCipherSuite()

返回包含協商的密碼套件資訊的列表。

getProtocol()

返回包含當前連線協商的SSL/TLS協議版本的字串。

getRemoteAddress()

獲取TLSSocket連線的對端地址。

getRemoteCertificate()

返回表示對等證書的物件。

getSignatureAlgorithms()

在伺服器和客戶端之間共享的簽名演演算法列表,按優先順序降序排列。

getState()

獲取TLSSocket連線的狀態。

off(type: 'close')

取消訂閱TLSSocket連線的關閉事件。

off(type: 'error')

取消訂閱TLSSocket連線的Error事件。

off(type: 'message')

取消訂閱TLSSocket連線的接收訊息事件。

on(type: 'close')

訂閱TLSSocket連線的關閉事件。

on(type: 'error')

訂閱TLSSocket連線的Error事件。

on(type: 'message')

訂閱TLSSocket連線的接收訊息事件。

send()

傳送資料。

setExtraOptions()

設定TLSSocket連線的其他屬性。

應用TCP/UDP協議進行通訊

UDP與TCP流程大體類似,下面以TCP為例:

1.      import需要的socket模組。

2.      建立一個TCPSocket連線,返回一個TCPSocket物件。

3.      (可選)訂閱TCPSocket相關的訂閱事件。

4.      繫結IP地址和埠,埠可以指定或由系統隨機分配。

5.      連線到指定的IP地址和埠。

6.      傳送資料。

7.      Socket連線使用完畢後,主動關閉。

import socket from '@ohos.net.socket'
// 建立一個TCPSocket連線,返回一個TCPSocket物件。
let tcp = socket.constructTCPSocketInstance();
// 訂閱TCPSocket相關的訂閱事件
tcp.on('message', value => {
  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 bindAddress = {
  address: '192.168.xx.xx',
  port: 1234, // 繫結埠,如1234
  family: 1
};
tcp.bind(bindAddress, err => {
  if (err) {
    console.log('bind fail');
    return;
  }
  console.log('bind success');
  // 連線到指定的IP地址和埠。
  let connectAddress = {
    address: '192.168.xx.xx',
    port: 5678, // 連線埠,如5678
    family: 1
  };
  tcp.connect({
    address: connectAddress, timeout: 6000
  }, err => {
    if (err) {
      console.log('connect fail');
      return;
    }
    console.log('connect success');
    // 傳送資料
    tcp.send({
      data: 'Hello, server!'
    }, err => {
      if (err) {
        console.log('send fail');
        return;
      }
      console.log('send success');
    })
  });
});
// 連線使用完畢後,主動關閉。取消相關事件的訂閱。
setTimeout(() => {
  tcp.close((err) => {
    console.log('close socket.')
  });
  tcp.off('message');
  tcp.off('connect');
  tcp.off('close');
}, 30 * 1000);

應用透過TLS Socket進行加密資料傳輸

開發步驟

客戶端TLS Socket流程:

1.      import需要的socket模組。

2.      繫結伺服器IP和埠號。

3.      雙向認證上傳客戶端CA證書及數字證書;單向認證上傳客戶端CA證書。

4.      建立一個TLSSocket連線,返回一個TLSSocket物件。

5.      (可選)訂閱TLSSocket相關的訂閱事件。

6.      傳送資料。

7.      TLSSocket連線使用完畢後,主動關閉。

import socket from '@ohos.net.socket'
   // 建立一個(雙向認證)TLS Socket連線,返回一個TLS Socket物件。
   let tlsTwoWay = socket.constructTLSSocketInstance();
   // 訂閱TLS Socket相關的訂閱事件
   tlsTwoWay.on('message', value => {
       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地址和埠。
   tlsTwoWay.bind({ address: '192.168.xxx.xxx', port: xxxx, family: 1 }, err => {
       if (err) {
           console.log('bind fail');
           return;
       }
       console.log('bind success');
   });
   // 設定通訊過程中使用引數
   let options = {
       ALPNProtocols: ["spdy/1", "http/1.1"],
       // 連線到指定的IP地址和埠。
       address: {
           address: "192.168.xx.xxx",
           port: xxxx, // 埠
           family: 1,
       },
       // 設定用於通訊過程中完成校驗的引數。
       secureOptions: {
           key: "xxxx",                            // 金鑰
           cert: "xxxx",                           // 數字證書
           ca: ["xxxx"],                           // CA證書
           passwd: "xxxx",                         // 生成金鑰時的密碼
           protocols: [socket.Protocol.TLSv12],    // 通訊協議
           useRemoteCipherPrefer: true,            // 是否優先使用對端密碼套件
           signatureAlgorithms: "rsa_pss_rsae_sha256:ECDSA+SHA256",    // 簽名演演算法
           cipherSuite: "AES256-SHA256",           // 密碼套件
       },
   };
   // 建立連線
   tlsTwoWay.connect(options, (err, data) => {
       console.error(err);
       console.log(data);
   });
   // 連線使用完畢後,主動關閉。取消相關事件的訂閱。
   tlsTwoWay.close((err) => {
       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.constructTLSSocketInstance(); // One way authentication
   // 訂閱TLS Socket相關的訂閱事件
   tlsTwoWay.on('message', value => {
       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地址和埠。
   tlsOneWay.bind({ address: '192.168.xxx.xxx', port: xxxx, family: 1 }, err => {
       if (err) {
           console.log('bind fail');
           return;
       }
       console.log('bind success');
   });
   // 設定通訊過程中使用引數
   let oneWayOptions = {
       address: {
           address: "192.168.xxx.xxx",
           port: xxxx,
           family: 1,
       },
       secureOptions: {
           ca: ["xxxx","xxxx"],            // CA證書
           cipherSuite: "AES256-SHA256",   // 密碼套件
       },
   };
   // 建立連線
   tlsOneWay.connect(oneWayOptions, (err, data) => {
       console.error(err);
       console.log(data);
   });
   // 連線使用完畢後,主動關閉。取消相關事件的訂閱。
   tlsTwoWay.close((err) => {
       if (err) {
           console.log("close callback error = " + err);
       } else {
           console.log("close success");
       }
       tlsTwoWay.off('message');
       tlsTwoWay.off('connect');
       tlsTwoWay.off('close');
   });


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70009402/viewspace-2986355/,如需轉載,請註明出處,否則將追究法律責任。

相關文章