2013-01-02 54 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