2013-01-02 53 views
2

我有另一个问题。无效的数据流头 - Java中的套接字传输

这是我的客户的一部分:

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。

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

迎接 亚历

+1

你为什么输入流复制到缓冲区,那么该缓冲区传递给一个ByteArrayInputStream? – benjarobin

+0

@benjarobin为什么会这样呢?听起来像是对我的暗示。 – nikk

回答

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

非常感谢你。这解决了我的问题! – alex

+0

我正在使用此解决方案,并且在服务器中出现错误。如果服务器不是我的电脑,我得到了无效的流头套接字。任何线索? –

+0

@FranzéJr。服务器很可能不在写入对象输出流。服务器使用什么有线协议? –

0

我同意彼得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) 
); 
+0

非常感谢!我将来会应用它。新年快乐 – alex