简体   繁体   English

如何从套接字读取 Json? 爪哇

[英]How do I read a Json from a socket? Java

I am doing a Server/Client network.我正在做一个服务器/客户端网络。 The messages are send as Json Objects.消息作为 Json 对象发送。 I have a method for writing the Json-Object but my method for reading the Json-Object doesnt work.我有一种编写 Json-Object 的方法,但我的读取 Json-Object 的方法不起作用。 I dont have any exceptions but there is no output like excpected.我没有任何例外,但没有像预期的输出。 Something must be wrong with the bufferedReader. bufferedReader 一定有问题。 I dont know how to get that Json-Object from the socket who sent it.我不知道如何从发送它的套接字中获取该 Json-Object。 Method for writing:写法:

public void writeMessage(JSONObject json) {
        try {
            PrintWriter printWriter = new PrintWriter(
                    new OutputStreamWriter(
                            socket.getOutputStream())); 
            printWriter.print(json);
            printWriter.flush();

        } catch (IOException writeMessageException) {
            System.out.println("!");

        }
    }

method for reading the message/ receiving the message:读取消息/接收消息的方法:

private static void readMessageFromServer(Socket socket) {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()))) 
    {
         StringBuilder sb = new StringBuilder();
            String readLine;
            while ((readLine = br.readLine()) != null) {
                sb.append(readLine);
            }
            JSONObject js = new JSONObject(sb.toString());
        String action1 = (String) js.get("action1");
    System.out.println(action1);
    } catch(IOException e) {
        System.out.println("!");
    }
    }

Thank you :)谢谢 :)

When reading data in bytes, we need to define our own protocol for communication between server and client.当以字节为单位读取数据时,我们需要为服务器和客户端之间的通信定义自己的协议。 The simplest protocol which we can define is called TLV (Type Length Value).我们可以定义的最简单的协议称为 TLV(类型长度值)。 It means that every *message written to the socket is in the form *of the Type Length Value.这意味着写入套接字的每个 * 消息都采用 * 类型长度值的形式。

So we define every message sent as:因此,我们将发送的每条消息定义为:

A 1 byte character that represents the data type, like s for String A 4 byte integer that indicates the length to the data And then the actual data, whose length was just indicated表示数据类型的 1 字节字符,如 s 表示字符串 4 字节整数,表示数据的长度 然后是实际数据,其长度刚刚指示

DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
char dataType = in.readChar();
int length = in.readInt();
    if(dataType == 's') {
        byte[] messageByte = new byte[length];
        boolean end = false;
        StringBuilder dataString = new StringBuilder(length);
        int totalBytesRead = 0;
        while(!end) {
            int currentBytesRead = in.read(messageByte);
            totalBytesRead = currentBytesRead + totalBytesRead;
            if(totalBytesRead <= length) {
                dataString
                  .append(new String(messageByte, 0, currentBytesRead, StandardCharsets.UTF_8));
            } else {
                dataString
                  .append(new String(messageByte, 0, length - totalBytesRead + currentBytesRead, 
                  StandardCharsets.UTF_8));
            }
            if(dataString.length()>=length) {
                end = true;
            }
        }
    }

More detail info can be found here https://www.baeldung.com/java-inputstream-server-socket更多详细信息可以在这里找到https://www.baeldung.com/java-inputstream-server-socket

  1. Consider using javax websocket .考虑使用javax websocket

javax.websocket client simple example javax.websocket 客户端简单示例

You can simply implement MessageHandler and specify the type parameter you expecting to receive using POJOs.您可以简单地实现MessageHandler并指定您希望使用 POJO 接收的类型参数。

    @Override
public void onOpen(Session session, EndpointConfig config) {
    session.addMessageHandler(new MessageHandler.Whole<MyJsonObject>() {

        @Override
        public void onMessage(MyJsonObject message) {
        //do something
        }
    });
}

That way you are creating a listener (@OnMessage) and handling each message as soon as it received.这样,您将创建一个侦听器 (@OnMessage) 并在收到每条消息后立即处理。 You can also implement MessageHandler with String type parameter and handle parsing the json yourself inside OnMessage method;您还可以使用 String 类型参数实现 MessageHandler 并在OnMessage方法中自己处理解析 json;

@Override
public void onOpen(Session session, EndpointConfig config) {
    session.addMessageHandler(new MessageHandler.Whole<String>() {

        @Override
        public void onMessage(String message) {
            MyJsonObject jObj = new ObjectMapper().readValue(message, MyJsonObject.class);
        }
    });
}
  1. If you want to stick with java net socket consider switching to Jackson Object Mapper from JSONObject, that way you can convert input stream into any object:如果您想坚持使用 java net socket,请考虑从 JSONObject 切换到Jackson Object Mapper ,这样您就可以将输入流转换为任何对象:

     private static void readMessageFromServer(Socket socket){ InputStream in = socket.getInputStream(); MyObject obj = new ObjectMapper().readValue(in, MyObject.class); }

more javax webSocket examples更多 javax webSocket 示例

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

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