简体   繁体   English

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

[英]ArrayBufferView Uncaught Error: INDEX_SIZE_ERR: DOM Exception 1

I send binary data over websocket from python server:我从 python 服务器通过 websocket 发送二进制数据:

data = struct.pack('!BI', 2, 1)
channel.send(channel.BINARY, data)

Data sending works fine.数据发送工作正常。 On client side javascript gets it like this:在客户端 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]);

How can this happen?这怎么会发生? Byte length minus byte offset is 4, and BYTY_ELEMENT_SIZE is also 4. First value is read without problems, but next always raise error, whatever type it is.字节长度减去字节偏移量是 4,BYTY_ELEMENT_SIZE 也是 4。读取第一个值没有问题,但接下来总是引发错误,无论它是什么类型。 Even if I only set byte offset like this即使我只像这样设置字节偏移量

var array2 = new Uint32Array(data,1);

there is an error.有一个错误。

One cannot create int32/uint32 array with offset not divisible by 4. The same for int16/uint16 and 2.不能创建偏移量不能被 4 整除的 int32/uint32 数组。int16/uint16 和 2 也是如此。

This is the limitation of CPU architecture.这是CPU架构的限制。

Let those 2 variables would be A:Uint16 and B:Uint8 .让这两个变量成为A:Uint16B:Uint8 You can map them onto bytes with different methods:您可以使用不同的方法将它们 map 到字节中:

  • BBAA (put value B into Uint16) BBAA (将值 B 放入 Uint16)
  • 0BAA / B0AA (skip 1 byte for alignment) 0BAA / B0AA (跳过 1 个字节进行对齐)
  • AAB (reorder for alignment). AAB (对齐重新排序)。

If you don't want to think about big-/little-endiad, reordering and other stuff... ie if you still want to put variables into bytes as BAA for some reason, then use the following idea:如果您不想考虑 big-/little-endiad、重新排序和其他东西...即,如果出于某种原因您仍想将变量作为BAA放入字节中,请使用以下想法:

For each not-aligned variable put into corresponding size buffer and copy it byte-by-byte.将每个未对齐的变量放入相应大小的缓冲区中并逐字节复制。 If misalign is 2 bytes, then copy may be made by pair of bytes.如果 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]);

BTW There's some ready code for packing/unpacking in js:顺便说一句,在 js 中有一些现成的打包/解包代码:

which are similar to php pack类似于php 包

My code may be more interesting to you, cause there're 2 classes: to pack into binary string and to pack into arraybuffer.我的代码对你来说可能更有趣,因为有 2 个类:打包成二进制字符串和打包成数组缓冲区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM