目录

Socket通信时,如何根据使用场景正确转换数据类型

问题现象

使用WebSocket、TCPSocket、TLSSocket、UDPSocket发送数据时,如何根据使用场景正确转换数据类型。

知识背景

解决方案

Socket数据传输仅支持string或ArrayBuffer数据类型,与服务器进行交互时,有以下五种场景:

完整示例参考如下:

function strToArrayBuffer(str: string) {
  let buf = new ArrayBuffer(str.length * 2);
  let bufView = new Uint16Array(buf);
  for (let i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  console.info(`bufView ${bufView}`);
  return bufView.buffer;
}

let inputValue = 'This is a plain string';
strToArrayBuffer(inputValue);

function strToInt8ArrayBuffer(str: string) {
  const arr = str.split(' ').map(hex => {
    let num = parseInt(hex, 16);
    return num > 127 ? num - 256 : num;
  });
  const typedArray = new Int8Array(arr);
  console.info(`typedArray ${typedArray}`);
  return typedArray.buffer;
}

let hexString = 'FA AF 11 C5 FE FF FF FF FF FF FF F0 53 C8 B9 25 E1 A7 67 46 68 94 1D 72 BC';
strToInt8ArrayBuffer(hexString);

function strToUint8ArrayBuffer(str: string) {
  const arr = str.split(' ').map(hex => {
    let num = parseInt(hex, 16);
    return num;
  });
  const typedArray = new Uint8Array(arr);
  console.info(`typedArray ${typedArray}`);
  return typedArray.buffer;
}

let hexValue = 'FA AF 11 C5 FE FF FF FF FF FF FF F0 53 C8 B9 25 E1 A7 67 46 68 94 1D 72 BC';
strToUint8ArrayBuffer(hexValue);

@Entry
@ComponentV2
struct SocketTest {
  build() {
    Column() {
      Button('普通字符串转buffer').onClick(() => {
        strToArrayBuffer(inputValue);
      });
      Button('16进制字符转Int8ArrayBuffer').onClick(() => {
        strToInt8ArrayBuffer(hexString);
      });
      Button('16进制字符转Uint8ArrayBuffer').onClick(() => {
        strToUint8ArrayBuffer(hexValue);
      });
    }
    .width('100%')
    .height('100%');
  }
}

常见FAQ

Q:同时启动多个tcp server去监听同样的端口,都可以成功,这种情况不应该抛出端口占用的异常吗?

A:目前如果遇到指定端口被占用的情况,tcpsocketserver的listen会自动绑定一个新的随机端口。

应用可以通过getLocalAddress获取监听的端口,判断是否与指定的一致。