【问题标题】:Java TCP simple communication gives unexpected resultsJava TCP 简单通信给出了意想不到的结果
【发布时间】:2011-10-30 16:20:55
【问题描述】:

我正在尝试在我的 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

我哪里做错了?

【问题讨论】:

  • 你试过把它读入一个字节[]?因为 8224 显然不适合一个字节

标签: java tcp hex


【解决方案1】:

如果你想发送字节,我建议你读字节,如果你想发送文本,我建议你读文本。您不应该尝试混搭,否则您可能会感到困惑。

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

【讨论】:

    【解决方案2】:

    您正在发送字节数组并仅读取一个字节。

    你必须像下面这样使用循环阅读:

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

    这会起作用,但它仍然不是您真正需要的。真的,您使用字符串进行操作,然后手动将字符串转换为字节数组,然后读取字节以便再次手动将它们转换为字符串?

    您应该使用 PrintWriter 来编写字符串:

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

    然后在读取数据时使用 BufferedReader。

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

    【讨论】:

    • 其实最后我想发送不是字符串的字节数组,所以我把字符串转换成字节数组进行测试。
    • 除非您保存 read() 返回的计数以便知道有多少字节,否则它将不起作用。并且在这段代码中读取永远不会返回零。
    【解决方案3】:

    摆脱所有的 ready() 测试。读取将阻塞,直到数据到达,因此调用 ready() 简直是在浪费时间,并且有丢失数据的风险。

    【讨论】:

      猜你喜欢
      • 2021-09-06
      • 2014-05-24
      • 1970-01-01
      • 1970-01-01
      • 2019-05-19
      • 2017-01-05
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多