2

我从 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

1 回答 1

0

不能创建偏移量不能被 4 整除的 int32/uint32 数组。int16/uint16 和 2 也是如此。

这是 CPU 架构的限制。

让这 2 个变量是A:Uint16B: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

我的代码对你来说可能更有趣,因为有 2 个类:打包成二进制字符串和打包成 arraybuffer。

于 2012-04-07T09:53:55.903 回答