簡體   English   中英

如何從套接字讀取 Json? 爪哇

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

我正在做一個服務器/客戶端網絡。 消息作為 Json 對象發送。 我有一種編寫 Json-Object 的方法,但我的讀取 Json-Object 的方法不起作用。 我沒有任何例外,但沒有像預期的輸出。 bufferedReader 一定有問題。 我不知道如何從發送它的套接字中獲取該 Json-Object。 寫法:

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("!");

        }
    }

讀取消息/接收消息的方法:

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("!");
    }
    }

謝謝 :)

當以字節為單位讀取數據時,我們需要為服務器和客戶端之間的通信定義自己的協議。 我們可以定義的最簡單的協議稱為 TLV(類型長度值)。 這意味着寫入套接字的每個 * 消息都采用 * 類型長度值的形式。

因此,我們將發送的每條消息定義為:

表示數據類型的 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;
            }
        }
    }

更多詳細信息可以在這里找到https://www.baeldung.com/java-inputstream-server-socket

  1. 考慮使用javax websocket

javax.websocket 客戶端簡單示例

您可以簡單地實現MessageHandler並指定您希望使用 POJO 接收的類型參數。

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

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

這樣,您將創建一個偵聽器 (@OnMessage) 並在收到每條消息后立即處理。 您還可以使用 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. 如果您想堅持使用 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); }

更多 javax webSocket 示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM