无效的流标头 - Java中的套接字传输

时间:2013-01-02 16:35:20

标签: java sockets serialization deserialization

我有另一个问题。

这是我客户的一部分:

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();

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

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

招呼 亚历

2 个答案:

答案 0 :(得分:4)

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

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();
}

答案 1 :(得分:0)

我同意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));

当您检测到End-Of-Stream条件时,您应该只退出此循环。换句话说,你永远不应该考虑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)
  );