自定義協議:`[10位長度數字][JSON數據]`,如 `0000000237{"CODE":"100"}`。需先讀取 10 字節長度,再按長度讀取 JSON。
InputStream in = socket.getInputStream();
byte[] buffer = new byte[10];
in.read(buffer); // 期望讀長度,實際可能讀到部分 JSON
原因:`read(buffer)` **不保證讀滿 buffer**,可能返回任意 1~10 字節;且流無標記,無法「退回」多讀的字節。
PushbackInputStream pin = new PushbackInputStream(socket.getInputStream());
// 1. 精確讀取 10 字節長度前綴
byte[] lenBytes = new byte[10];
int totalRead = 0;
while (totalRead < 10) {
int r = pin.read(lenBytes, totalRead, 10 - totalRead);
if (r == -1) throw new EOFException("連接關閉");
totalRead += r;
}
int dataLength = Integer.parseInt(new String(lenBytes, StandardCharsets.US_ASCII).trim());
// 2. 精確讀取數據體
byte[] data = new byte[dataLength];
totalRead = 0;
while (totalRead < dataLength) {
int r = pin.read(data, totalRead, dataLength - totalRead);
if (r == -1) throw new EOFException("數據不完整");
totalRead += r;
}
// 3. 解析 JSON
String json = new String(data, StandardCharsets.UTF_8);
// JSONObject obj = new JSONObject(json);
// 假設一次性 read 大 buffer,需把多讀的推回
byte[] bigBuf = new byte[1024];
int n = pin.read(bigBuf); // 實際只需 10 字節長度
if (n > 10) {
pin.unread(bigBuf, 10, n - 10); // 將多讀的字節推回流頭
}
// 後續 read 會先返回推回的字節