在服务器端代码中,我需要能够侦听套接字,以与同一台机器上的Java 7测试应用程序交换JSON“数据包”。 Java测试应用程序建立了连接,并构造了一个JSON字符串并将其写入套接字。它由Dart服务器端应用程序接收,并传递给回调方法handleJson,该方法尝试对其进行解码。该进程死于“JSON.decode”。
我认为它之所以死是因为该字符串由Java'writeUTF'方法加上一个短整数组成,该整数包含一个短整数,该整数包含JSON UTF-8中的字节数(不包括前导短整数和前导字节为0)。
在我的Java测试应用程序中写入套接字之前的JSON字符串:
{"target":"DOOR","command":"OPEN"} // 34 characters
Java代码段:
// in a try-catch
Socket client = new Socket(serverName, port);
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF(json);
client.close();
Java文档指出,out.writeUTF方法将json字符串转换为UTF-8,其字符串长度以包含写入的字节总数的short int开头。
在主要方面:
ServerSocket.bind('127.0.0.1', 4041)
.then((serverSocket) {
print('connected');
// prints: 'connected'
serverSocket.listen((socket) {
socket.transform(UTF8.decoder).listen(handleJson);
});
});
handleJson方法:
handleJson(String stringAsJson){
print('string length is ' + (stringAsJson.length).toString());
// prints: 'string length is 36'
print('received json $stringAsJson');
// prints: 'received json '
String json = JSON.decode(stringAsJson);
// dies on decode
print('Sever Socket received: $json');
}
最佳答案
这将给您带来一些麻烦,因为Socket是原始TCP,而TCP是流式传输。这意味着您发送的文本(字节)可以按照网络认为合适的任何方式进行拆分和合并。
对于您的情况,您需要一种方法来标记每条JSON消息的结尾。一个示例可能是累积接收到的所有字节,直到看到字节0(在JSON中无效)为止。然后可以将这些字节转换为UTF8,然后再次转换为JSON。请注意,对等方需要在消息之间发送此0字节,才能正常工作。
现在,您还考虑使用WebSockets作为发送消息的方法。在最初的HTTP握手之后,它实际上只是一个原始TCP套接字,带有一些额外的 header 信息,以使其面向软件包-正是您所需要的。 dart:io
已经包含WebSocket实现。