簡體   English   中英

Java TCP簡單通信帶來了意想不到的結果

[英]Java TCP simple communication gives unexpected results

我正在嘗試在Java程序中通過TCP發送一些簡單的數據:

         String data = "70798090999a9b9c9d9e9fa0a1a2";
             ServerSocket srvr = new ServerSocket(1234);
             Socket skt = srvr.accept();
             OutputStream out = skt.getOutputStream();
             out.write(hexStringToByteArray(data));
             out.close();
             skt.close();
             srvr.close();

具有功能:

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

並以以下方式接收數據:

     Socket skt = new Socket("localhost", 1234);
     BufferedReader in = new BufferedReader(new
        InputStreamReader(skt.getInputStream()));

     while (!in.ready()) {}
     while (in.ready()) {
     System.out.println(in.read()); // Read one line and output it
     }

但是我沒有收到通常會遞增的數字列表,而是隨心所欲地增加和減少了一些東西:

121
196
234
244
246
245
250
249
251
252
8224
176
162

我在哪里做錯了什么?

您正在發送字節數組,並且僅讀取一個字節。

您必須閱讀using循環,如下所示:

byte[] arr = new byte[1024];
while (in.read(arr) >= 0) {
    // do something with the data.
}

這將起作用,但仍然不是您真正需要的。 確實,您使用字符串進行操作,但是隨后將字符串手動轉換為字節數組,然后讀取字節以再次將它們手動轉換為String?

相反,您應該使用PrintWriter編寫字符串:

PrintWriter writer = new PrintWriter(new OutputStreamWriter(out));
writer.write(str);

然后在讀取數據時使用BufferedReader。

BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = reader.readLine();

如果要發送字節,我建議您閱讀字節,如果要發送文本,我建議您閱讀文本。 您不應該嘗試混合搭配,否則可能會感到困惑。

byte[] bytes = new BigInteger("70798090999a9b9c9d9e9fa0a1a2", 16).toByteArray();

ServerSocket ss = new ServerSocket(1234);
Socket c = new Socket("localhost", 1234);
Socket s = ss.accept();
final OutputStream out = s.getOutputStream();
out.write(bytes.length);
out.write(bytes);

final DataInputStream in = new DataInputStream(c.getInputStream());
int length = in.read();
byte[] bytes2 = new byte[length];
in.readFully(bytes2);

System.out.println(new BigInteger(1, bytes2).toString(16));
c.close();
s.close();
ss.close();

版畫

70798090999a9b9c9d9e9fa0a1a2

擺脫所有ready()測試。 讀取將阻塞,直到數據到達為止,因此調用ready()確實浪費時間,並且有丟失數據的風險。

暫無
暫無

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

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