ArrayBufferView未捕获错误:INDEX_SIZE_ERR:DOM异常1

ArrayBufferView Uncaught Error: INDEX_SIZE_ERR: DOM Exception 1

本文关键字:SIZE ERR DOM 异常 INDEX 错误 ArrayBufferView      更新时间:2023-09-26

我通过网络套接字从python服务器发送二进制数据:

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体系结构的局限性。

设这两个变量为A:Uint16B:Uint8。你可以用不同的方法将它们映射到字节上:

  • BBAA(将值B放入Uint16)
  • 0BAA/B0AA(跳过1个字节进行对齐)
  • AAB(重新排序以对齐)

如果你不想考虑大/小endiad、重新排序和其他事情。。。即,如果出于某种原因,您仍然希望将变量作为BAA放入字节中,那么请使用以下思想:

对于每个未对齐的变量,将其放入相应大小的缓冲区并逐字节复制。如果未对齐是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:中有一些现成的打包/拆包代码

  • 矿井
  • phpjs

类似于php包

我的代码可能更有趣,因为有两个类:打包到二进制字符串和打包到arraybuffer。