我从 python 服务器通过 websocket 发送二进制数据:
data = struct.pack('!BI', 2, 1)
channel.send(channel.BINARY, data)
数据发送正常。 在客户端 javascript 是这样获取的:
onbinarydata: function(data) {
alert(data.byteLength);
>> 5
var array = new Uint8Array(data,0,1);
alert(array[0]);
>> 2
var array2 = new Uint32Array(data,1,5);
>> Uncaught Error: INDEX_SIZE_ERR: DOM Exception 1
alert(array2[0]);
这怎么会发生? 字节长度减字节偏移为4,BYTY_ELEMENT_SIZE也为4。 读取第一个值没有问题,但接下来总是会引发错误,无论它是什么类型。 即使我只像这样设置字节偏移量
var array2 = new Uint32Array(data,1);
有一个错误。
请您参考如下方法:
不能创建偏移量不能被 4 整除的 int32/uint32 数组。对于 int16/uint16 和 2 也是如此。
这是CPU架构的限制。
让这 2 个变量为 A:Uint16 和 B:Uint8。您可以使用不同的方法将它们映射到字节:
BBAA(将值 B 放入 Uint16)0BAA/B0AA(对齐跳过 1 个字节)AAB(对齐重新排序)。
如果您不想考虑 big-/little-endiad、重新排序和其他东西...即,如果出于某种原因您仍想将变量放入字节中作为 BAA,那么使用以下想法:
对于每一个不对齐的变量放入相应大小的缓冲区,逐字节复制。 如果misalign为2个字节,则可以按对字节进行复制。
var array = new Uint8Array(data,0,1);
alert(array);
var array2 = new Uint8Array(data,1,5);
var abuf2 = new ArrayBuffer(4);
var abuf2_8 = new Uint8Array(abuf2);
// using `subarray` won't help, cause it doesn't create a copy like `slice`
// and the same data will have the same inconsistent memory alignment
for (var i = 0; i < 4; i++) abuf2_8[i] = array2[i];
var abuf2_32 = new Uint32Array(abuf2);
alert(abuf2_32[0]);
顺便说一句,在 js 中有一些现成的打包/解包代码:
类似于php pack
我的代码对你来说可能更有趣,因为有两个类:打包成二进制字符串和打包成数组缓冲区。
