【问题标题】:ObjectOutputStream.writeBytes(String s) unexpected output valuesObjectOutputStream.writeBytes(String s) 意外的输出值
【发布时间】:2016-10-15 07:26:50
【问题描述】:

我正在使用ObjectOutputStream 对象操作系统将字符串消息从客户端 Android 应用程序发送到 c++ 服务器。

我知道服务器必须如何接收我的消息: msg 的每个字符都存储在一个字节数组(received_msg[])中。我也知道服务器期望的确切消息(通过另一个 c++ 应用程序)。

我发送的数据是一个由 1 个字节数组和 2 个其他字符串组成的字符串。

我的问题: 我已经使用PrintWriter 发送我的数据,但我的服务器总是会在received_msg 中显示一些奇怪的字符,在索引24 到28 处。 我尝试了很多转换来修复它,但放弃了。 所以我尝试用ObjectOutputStream 发送味精。 客户端使用ObjectOutputStream.writeBytes(),服务器显示几乎正确的接收到的消息。几乎是因为开头加了一些字符。

类似的东西: 在服务器收到_msg:

index 0: ┐

index 1: i

index 2: ''

index 3: |

index 4: I //beginning of the message I actually wanted to send

index 5: S //every char following index 4 is good.

而在“我”之前,我什么也没发送。 我发送的消息是这样开始的:ISOXXXXXX

所以我想知道是否有任何方法可以检索 ObjectOutputStream.writeBytes 的真实输出。我知道它是输出,而不是输入,这仍然可以帮助我理解它是如何添加奇怪的标题的。

提前感谢您的建议

我的发送功能

private void send(String o) {
    System.out.println("socket");
    try {
        this.socket = new Socket(serverIP, portNumber);
        os = new ObjectOutputStream(socket.getOutputStream());
        //OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
        //InputStreamReader in = new InputStreamReader(socket.getInputStream());
        // PrintWriter pw = new PrintWriter(out, true);

        System.out.println("Connected to server : " + this.socket.getInetAddress() + " on port " + this.socket.getPort());
        System.out.println("from local address: " + this.socket.getLocalAddress() + " and port: " + this.socket.getLocalPort());
        System.out.println("02. -> Sending an object...");

        ArrayList<String>  tempoStr = StringToByteArray(o);
        String msg="";
        for(String inStr :tempoStr)
             msg+=inStr;
        System.out.println("the message I ACTUALLY send is\n"+msg); //the result in console is EXACTLY the message I expect.
        os.writeBytes(msg); //then when I check on the server:  unexpected additionnal chars at the beginning.
        os.flush();
       // pw.write(msg);
       //pw.flush();
        System.out.println("send success");
    } catch (IOException e) {
        e.printStackTrace();
        System.out.println("XX. Exception Occurred on Sending:" +  e.toString() +"\n"+ e.getCause());
        System.out.println("Socket creation failure or error on sending.");

    }
}

PS:我无法更改服务器代码。

【问题讨论】:

  • OOS 的 .writeString() 会写入修改后的 UTF,这肯定不是你想要的。另外,编码是什么? ASCII?
  • ObjectOutputStream 将 Java 对象的原始数据类型和图形写入 OutputStream
  • 我使用 ASCII 编码。我发送的消息是:msg = "ISOxxxxxxxxxxxxxxp ������ÀXXXXXX��&XXXXXXX",其中 X 是数字。我只是想把它发送到服务器。并且服务器完全接收它,但似乎在开头添加了其他字符。

标签: java android objectoutputstream


【解决方案1】:

使用 ObjectOutputStream(仅限 java)。有人可能会使用 DataOutputStream,但在这里您似乎想要一些简单的东西。

byte[] a = ...
String b = ...

OutputStream out = ...
out.write(a);
out.write((b + '\u0000').getBytes("UTF-8")); // Or "Windows-1252" / "ISO-8859-1"
out.flush();

我添加了一个'\0',因为它在 C/C++ 中用于终止字符串(二进制输出)。 或者可能需要"\r\n"文本输出)。

编码是明确给出的。

【讨论】:

  • 我找到了这个链接:stackoverflow.com/questions/28583168/…。他们说:“原始数据,不包括可序列化字段和可外部化数据,以块数据记录的形式写入 ObjectOutputStream。块数据记录由标头和数据组成。块数据标头由标记和字节数组成跟随标题。“我认为我需要摆脱标题
  • 建议也改用(File)OutputStream - 即:直接写入原始字节。从您的 cmets 看来,字节部分也是文本? java中的文本在内部是Unicode,所以要以某种编码X获取字节,需要指定X,或者反过来从字节获取文本字符串,最好指定它们的编码。
  • 我尝试了您的解决方案 Joop Eggen,但我仍然有标题。我将尝试与 FileInput/OutputStream 链接的 DataInput/OutputStream。我已经在尝试写入原始字节上浪费了很多时间,我更愿意发送字符串...
  • 恕我直言 DataInput/OutputStream 不会带来更快的解决方案。以数字形式转储字节,检查它们的来源。
  • 都是ASCII编码的。是的,字节部分也是文本。只是当我改变我的写作方式时这部分会改变(PrinterWrite,ObjectOutputStream.writeBytes,......每个对字节部分的文本都有不同的结果)。我发现使用 ObjectOutputStream.writeBytes,收到的消息带有我想要的字符......以及附加的标题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 2020-02-21
  • 2012-05-06
  • 2019-03-21
相关资源
最近更新 更多