我的服务器端Dart应用程序从套接字接收JSON字符串。该字符串由Java代码生成。当字符串在Java代码中发送到套接字时,它被编码为UTF8,并且字符串前面加上两个字节,一个短的int。此short的值是字符串+2中的字节数。
我需要将该值提取为int以便处理字符串,但我尝试过的任何工作都没有。它死于JSON.decode(下面),因为它遇到了另一个JSON字符串的开头。第二个字符串的第一个字节是带有第二个JSON字符串长度的start short。这两个字符串每个都少于40个字符。
(我还需要将长度附加到从Dart发送到Java的字符串。)
Java line
out.writeUTF(json); // converts and writes to the socket stream.
Dart服务器端代码方法
handleJavaSocket(Socket javasocket){
javasocket.transform(UTF8.decoder).listen((String socketString){
var truncated = socketString.substring(2);
String message = JSON.decode(truncated); // dies here
// more code
}, onError: (error) {
print('Bad JavaSocket request');
});
}
编码前的一个JSON字符串
{"target":"DOOR","command":"OPEN"}
答案 0 :(得分:2)
所以你总是以[sizeuper8,sizelower8,.. utf8-string ...]作为你的信息边界发送? UTF8解码并不期望长度作为参数,并将两个字节视为unicode(可能为null后跟一个字符)。
我目前正在为Quiver(https://pub.dartlang.org/packages/quiver)开发StreamBuffer,它可以让你将套接字传递给一个缓冲区,为你提供:
read(2).then((bytes) => read(bytes[1]<<8|bytes[2]).then((string) => UTF8.decode(string)));
您可以在此之后发布已解码的字符串,但它应该对您的数据进行解复用。
当前拉取请求(正在进行的工作):https://github.com/google/quiver-dart/pull/117
答案 1 :(得分:0)
我找不到将两个字节头转换为整数的方法,特别是因为一个字节可能是0而某些字符串方法将其视为字符串终止符。
由于来自Java应用程序的消息将始终由标题后跟消息组成,我忽略标题并解析来自Stream的消息将它们添加到列表中(以便将它们作为验证回显),
然后我遍历列表并通过写入一个0字节,然后将消息大小写入流流,然后写入消息来模拟标题。这不会像消息长度大于255那样工作,但我不希望任何甚至接近那个大小。
应该注意Dart应用程序和Java应用程序在同一台机器上。
handleJavaSocket(Socket javasocket){
// echo socket
javasocket.transform(UTF8.decoder).forEach((item) {
var start = 2;
var end = -1;
var messages = new List<String>();
while((++end < item.length) && (end = item.indexOf('}',end)) != -1) {
messages.add(item.substring(start, ++end));
start = end + 2;
}
for(var message in messages) {
// header message length as two bytes
javasocket.writeCharCode(0); // max length 254
javasocket.writeCharCode(message.length);
javasocket.write(message); // <== send
}
});
}