在下面的服务器/客户端套接字代码中,服务器尝试将int从0发送到1023。客户端接收到正确数量的int,但它们以255换行。这是为什么,正确的方法是什么?
import 'dart:async';
import 'dart:io';
main() async {
final server = await ServerSocket.bind('127.0.0.1', 4041);
server.listen((Socket socket) {
print('Got connected ${socket.remoteAddress}');
for(int i=0; i<1024; i++) {
socket.add([i]);
}
socket.close();
print('Closed ${socket.remoteAddress}');
});
}
Run Code Online (Sandbox Code Playgroud)
import 'dart:async';
import 'dart:io';
main() async {
final client = await Socket.connect('127.0.0.1', 4041);
client.listen(
(var data) => print('Got $data'),
onDone: () { print('Done'); client.close(); },
onError: (e) { print('Got error $e'); client.close(); });
print('main done');
}
Run Code Online (Sandbox Code Playgroud)
而且,感觉Socket API有点不同-与其他语言相比,它比Dartish更支持它作为流读取的方式。但是,如果您只想读取N个字节怎么办?您如何实现的?我看到了take方法(Stream take(int count)),但是我不清楚到底是什么计数,尤其是在读取了多少字节方面。因为Socket实现了Stream <List <int>>,并且因为int并不是一个固定大小的实体(我认为?),所以您如何知道已读取了多少字节?
需要说明的一件事是,即使大多数方法都针对Dart中所有IO 的基本假设进行dart:io操作,List<int>但这些方法都是这些字节值列表。文档可能不那么精确。
这意味着您可以List在发送字节时使用所需的任何实现,包括键入的数据,例如
var socket = ...
socket.add([1, 2, 3]);
socket.add(new List<int>.generate(3, (int index) => index * index);
socket.add('ASCII'.codeUnits);
socket.add(UTF8.encode('Søren'));
var typedData = new Uint8List(8);
var data = new ByteData.view(typedData.buffer);
data.setInt32(0, 256 * 256 - 1);
data.setInt32(4, 256 * 256 - 1, Endianness.LITTLE_ENDIAN);
socket.add(typedData)
Run Code Online (Sandbox Code Playgroud)
从套接字接收数据时,Socket流中传递的数据是从OS传递的字节块。您无法预测此时将接收多少字节。如果您希望能够读取特定数量的字节,则一个选择是实现一个字节读取器,该读取器具有如下方法:
Future<List<int>> read(int numBytes);
Run Code Online (Sandbox Code Playgroud)
然后可以使用的流初始化此字节读取器List<int>并处理该帧。您可以做的是有一个缓冲区(也许可以BytesBuilder从中使用dart:io),以便在接收到数据时收集数据。当足够的字节可用时,read称为Future完成。这样的字节读取器还可以在缓冲的数据量达到一定限制时暂停流,并在读取数据时再次恢复流。
| 归档时间: |
|
| 查看次数: |
1826 次 |
| 最近记录: |