首先,您不需要将数据字符串转换为十六进制值,以便通过 TCP 发送它。 node.js 中的每个字符串在通过网络发送时都会转换为字节。
通常,您会像这样发送字符串:
var data = "ABC";
socket.write(data); // will send bytes 65 66 67, or in hex: 44 45 46
Node.JS 还允许您将Buffer 对象传递给.write() 等函数。
因此,实现您想要的最简单的方法可能是创建一个适当的缓冲区来保存您的数据。
var data = "ABC";
var prefix = 0x0F; // JavaScript allows hex numbers.
var suffix = 0x0FC1;
var dataSize = Buffer.byteLength(data);
// compute the required buffer length
var bufferSize = 1 + dataSize + 2;
var buffer = new Buffer(bufferSize);
// store first byte on index 0;
buffer.writeUInt8(prefix, 0);
// store string starting at index 1;
buffer.write(data, 1, dataSize);
// stores last two bytes, in big endian format for TCP/IP.
buffer.writeUInt16BE(suffix, bufferSize - 2);
socket.write(buffer);
说明:
prefix 十六进制值 0F 需要 1 个字节的空间。 suffix 十六进制值 0FC1 实际上需要两个字节(一个 16 位整数)。
在计算字符串所需的字节数时(JavaScript 字符串是 UTF-16 编码的!),str.length 在大多数情况下并不准确,尤其是当您的字符串包含非 ASCII里面的人物。为此,获取字符串字节大小的正确方法是使用Buffer.byteLength()。
node.js 中的Buffers 具有静态分配,这意味着您在创建它们后无法调整它们的大小。因此,您需要在创建缓冲区 -in bytes- 之前计算它的大小。查看我们的数据,即1(我们的前缀)+Buffer.byteLength(data)(我们的数据)+2(我们的后缀)。
之后-将缓冲区想象为字节数组(8 位值)-,我们将填充缓冲区,如下所示:
- 使用
writeUInt8(byte, offset)在我们的缓冲区中写入第一个字节(prefix),偏移量为0。
- 写入数据字符串,使用
.write(string[, offset[, length]][, encoding]),从我们缓冲区中的偏移量1开始,长度为dataSize。
- 写入最后两个字节,使用
.writeUInt16BE(value, offset) 偏移bufferSize - 2。我们正在使用 writeUInt16BE 以 big-endian 编码写入 16 位值,这正是 TCP/IP 所需要的。
一旦我们用正确的数据填充缓冲区,我们就可以使用socket.write(buffer)通过网络发送它;
附加提示:
如果您真的想将大字符串转换为字节,(例如,稍后打印为十六进制),那么Buffer 也很棒:
var buf = Buffer.from('a very large string');
// now you have a byte represetantion of the string.
由于字节都是 0-255 十进制值,您可以在控制台中轻松地将它们打印为十六进制值,如下所示:
for (i = 0; i < buf.length; i++) {
const byte = buf[i];
const hexChar = byte.toString(16); // convert the decimal `byte` to hex string;
// do something with hexChar, e.g. console.log(hexChar);
}