【问题标题】:Invalid Stream Header - Socket Transfer in Java无效的流标头 - Java 中的套接字传输
【发布时间】:2012-12-17 00:45:26
【问题描述】:

我还有一个问题。

这是我客户的一部分:

Socket socket = new Socket("127.0.0.1", 3000);
            OutputStream out = socket.getOutputStream();

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutput oo = null;
            try {
              oo = new ObjectOutputStream(bos);   
              oo.writeObject(mp3dataStrings);
              byte[] serializedMP3 = bos.toByteArray();
              out.write(serializedMP3);
                out.flush();
            } finally {
              oo.close();
              bos.close();
            }   

这是我服务器的一部分:

ServerSocket clientConnect = new ServerSocket(port);
        System.out.println("SimpleServer running on port" + port);
        Socket clientSock = clientConnect.accept();
        InputStream is = clientSock.getInputStream();

        byte[] buffer = new byte[1024];

        for (int i = 0; i < buffer.length; i++) {
          int b = is.read();
          buffer[i] = (byte) b;
          if (b == -1 | b == 0) break;
        }
        ObjectInputStream stream = new ObjectInputStream(new ByteArrayInputStream(buffer));
        String[][] songs = (String[][]) stream.readObject();
        stream.close();

当我发送我的对象(字符串[][])时,我得到异常无效的流标头:ACED0000。

我找不到这意味着什么以及我必须做什么。

问候 亚历克斯

【问题讨论】:

  • 为什么将输入流复制到缓冲区,然后将此缓冲区传递给 ByteArrayInputStream ?
  • @benjarobin 为什么会有问题?听起来像是对我的暗示。

标签: java sockets serialization deserialization


【解决方案1】:

你让它变得比你需要的复杂得多。

Socket socket = new Socket("127.0.0.1", 3000);
try {
  ObjectOutputStream oo = new ObjectOutputStream(socket.getOutputStream());   
  oo.writeObject(mp3dataStrings);
  oo.close();
} finally {
  socket.close();
}   

ServerSocket clientConnect = new ServerSocket(port);
System.out.println("SimpleServer running on port" + port);

Socket clientSock = clientConnect.accept();
try {
  ObjectInputStream stream = new ObjectInputStream(clientSock.getInputStream());
  String[][] songs = (String[][]) stream.readObject();
} finally {
  clientSock.close();
}

【讨论】:

  • 我正在使用此解决方案,但服务器出现错误。如果服务器不是我的计算机,我得到无效的流标头套接字。有什么线索吗?
  • @FranzéJr。服务器很可能没有写入对象输出流。服务器使用什么有线协议?
  • 现在可以使用了。可能是一些“干净”的问题。谢谢你们。
【解决方案2】:

我同意 Peter Lawrey 的回答,但是您原始代码中的问题源于字节缓冲区填充代码中的退出条件

    byte[] buffer = new byte[1024];

    for (int i = 0; i < buffer.length; i++) {
      int b = is.read();
      // THIS ARE PROBLEM LINES
      buffer[i] = (byte) b;
      if (b == -1 | b == 0) break;
    }
    ObjectInputStream stream = 
      new ObjectInputStream(new ByteArrayInputStream(buffer));

只有在检测到流结束条件时才应退出此循环。换句话说,您永远不应该考虑b==0,因为它是 ObjectInputStream 的有效部分。

其次,在检查中断条件之前不应将字节分配给缓冲区。

第三,如果你初始化 ByteArrayInputStream,你应该只传递包含输入的字节数,而不是整个缓冲区本身。

修正后的方块应该是这样的:

// How do you know if 1024 is enough to get all data?
// For the sake of this example, assume it's enough
byte[] buffer = new byte[1024];

int count = 0;
for (; count < buffer.length; count++) {
  int b = is.read();

  if ( b == -1 )
  {
    // exit only on End-Of-Stream, and do not record
    // this result into the buffer
    break;
  }

  buffer[count] = (byte) b;
}

ObjectInputStream stream = 
  new ObjectInputStream( 
    // Note, that we are now passing the number of 'active' bytes in the buffer
    new ByteArrayInputStream(buffer, 0, count)
  );

【讨论】:

  • 非常感谢!我将来会应用它。新年快乐
猜你喜欢
  • 2021-04-29
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 2011-02-07
  • 2013-02-02
相关资源
最近更新 更多