首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么'_Uint8ArrayView‘可能返回到Dart命令行客户端的websocket onData处理程序?

为什么'_Uint8ArrayView‘可能返回到Dart命令行客户端的websocket onData处理程序?
EN

Stack Overflow用户
提问于 2014-12-28 05:57:20
回答 2查看 2.3K关注 0票数 1

我有一个命令行Dart脚本客户端在dart上进行交互:io websocket与Jetty服务器交互。我实现了一个自定义消息子协议,它使用反射(两边)使用二进制编码将Dart对象与Jetty中的Java对象交换。PODO -> Uint8List -> -> ByteBufer -> POJO (并反向返回)。本地往返单元测试在任何一方(即PODO -> Uint8List -> PODO;POJO -> ByteBuffer -> POJO)上都正确执行。我使用一系列简单的“string”交换来测试与不同服务端点的连接。从Dart到Jetty的传输可以工作,但是响应数据虽然收到正确,但产生了一种奇怪的类型,我不理解,解码器也不把它理解为Uint8List、ByteBuffer等。

虽然我不能轻易地将其提取为一个小示例,但下面是相关的代码和一些输出:

Dart客户端:

代码语言:javascript
复制
WebSocket.connect(url).then((WebSocket socket) {
  _log.finer('connected');
  _websocket = socket
    ..listen(_onResponse, onError: (e, StackTrace st) => print('Session error: $e; $st'));
  ...
}

_onResponse(data) {
  print('response raw data: $data');
  InstanceMirror im = reflect(data);
  print('instance: $im');
  ...
  decode(data)
}

decode(Uint8List data) {
  var b = data.buffer;
  ByteData bd = new ByteData.view(b);
  int offset = 0;
  const ENDIANNESS = Endianness.LITTLE_ENDIAN;

  int msgLength = bd.getInt32(offset, ENDIANNESS); // is 6645122; should be 101
  ...
}

输出:

代码语言:javascript
复制
    response raw data: [101, 0, 0, 0, ...]
    instance: InstanceMirror on Instance of '_Uint8ArrayView'

IntelliJ调试器显示:

代码语言:javascript
复制
    data = {List[id=1]} size = 101
    > im = {_LocalInstanceMirror[id=2]} InstanceMirror on Instance of '_Uint8ArrayView'
        _reflectee = {List[id=1]}
        _type = null
        hasReflectee = true
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-28 21:26:55

“data.buffer”访问的缓冲区是支持“data”引用的Uint8List视图的内部缓冲区。传输的有效载荷--我想用ByteData视图包装的东西--被一些字节抵消到这个缓冲区中。有效负载的“偏移”可以通过“数据”对象的“offsetInBytes”属性来确定。对decode()的以下更改使使用ByteData API解码负载字节数组的各个片段成为可能:

代码语言:javascript
复制
int offset = data.offsetInBytes; // sets offset to the starting position of the payload
int msgLength = bd.getInt32(offset);
double somethingElse = bd.getFloat64(offset+4);
// etc.
票数 1
EN

Stack Overflow用户

发布于 2014-12-28 09:54:44

Dart支持一般的ByteBuffer类型,它只是表示字节的列表,如您在这里所看到的:

data.ByteBuffer

由于ByteBuffer类是抽象,因此可以通过接收ByteBuffer对象或实例化新列表来创建列表。列表通常是固定长度的,使用它是很困难的。这就是为什么可以从视图创建ByteBuffer的原因。视图表示ByteBuffers字节的子集,由offsetlength提供,它们也可能是整个缓冲区。

让我们看一个小例子:

代码语言:javascript
复制
import 'dart:typed_data';

void main() {
  Uint8List data8 = new Uint8List.fromList([1,2,3,4,5,6,256]);
  Uint16List data16 = new Uint16List.fromList([1,2,3,4,5,6,256]);

  print(data8);
  print(data16);

  print(data8.buffer.lengthInBytes);
  print(data16.buffer.lengthInBytes);

  print(data16.buffer.asUint8List());
  print(data16.buffer.asUint16List());
}

这给了你:

代码语言:javascript
复制
[1, 2, 3, 4, 5, 6, 0] // List
[1, 2, 3, 4, 5, 6, 256] // List
7
14
[1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, 1] // View
[1, 2, 3, 4, 5, 6, 256] // View

这意味着: ByteBuffer是一些抽象类,它为您提供了接口和基本功能,您可以从缓冲区获得视图,以便在需要时访问数据。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27674032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档