2014-04-24 31 views
2

好的,我有一段代碼應該通過套接字發送多個文件。我在for循環中這樣做的方式我打開一個套接字 - >傳輸文件 - >關閉套接字,然後重複其他文件。上述代碼如下它:通過套接字傳輸時發生隨機錯誤

for (int i = 0; i < fname.size(); i++) { 
      Socket sok = new Socket("localhost",4444); 
      PrintStream oos = new PrintStream(sok.getOutputStream()); 
      oos.println("1"); 
      try { 

       System.out.println(fname.get(i)); 
       File myFile = new File(path+fname.get(i)); 
       byte[] mybytearray = new byte[(int) myFile.length()]; 

       FileInputStream fis = new FileInputStream(myFile); 
       BufferedInputStream bis = new BufferedInputStream(fis); 
       // bis.read(mybytearray, 0, mybytearray.length); 

       DataInputStream dis = new DataInputStream(bis); 
       dis.readFully(mybytearray, 0, mybytearray.length); 

       OutputStream os = sok.getOutputStream(); 

       // Sending file name and file size to the server 
       DataOutputStream doss = new DataOutputStream(os); 
       doss.writeUTF(myFile.getName()); 
       doss.writeLong(mybytearray.length); 
       doss.write(mybytearray, 0, mybytearray.length); 
       doss.flush(); 
       sok.close(); 
       System.out.println("File " + fname.get(i) + " sent to Server."); 

      } catch (Exception e) { 
       System.err.println("File does not exist! (May not be true) Generated Error: "+e); 
      } 


      //sendFile(path+fname.get(i)); 
      //sock.close(); 
     } 
    } catch (Exception e) { 
     System.err.println(e); 
    } 

現在發生的事情是客戶端沒有吐出任何錯誤,事實上,目前它實際上說,文件被髮送到服務器。現在服務器吐出了隨機錯誤。有時服務器會收到一些文件(從來都不是全部文件),有時它不會收到任何文件,而且出現的錯誤也是隨機的。錯誤是以下一項或其組合:

java.io.EOFException 
java.io.FileNotFoundException 
java.net.SocketException: Connection reset 
java.io.UTFDataFormatException 

所有這些錯誤都是在服務器端嘗試傳輸時發生的。我不知道這到底是怎麼回事=/

服務器代碼:

public void receiveFile() { 


    try { 
     int bytesRead; 

     DataInputStream clientData = new DataInputStream(
       clientSocket.getInputStream()); 

     String fileName = clientData.readUTF(); 
     OutputStream output = new FileOutputStream((fileName)); 
     long size = clientData.readLong(); 
     byte[] buffer = new byte[100000]; 
     while (size > 0 
       && (bytesRead = clientData.read(buffer, 0, 
         (int) Math.min(buffer.length, size))) != -1) { 
      output.write(buffer, 0, bytesRead); 
      size -= bytesRead; 
     } 

     output.close(); 
     clientData.close(); 

     System.out.println("File " + fileName + " received from client."); 
    } catch (IOException ex) { 
     System.err.println("Client error. Connection closed.  " +ex); 
    } 
} 

堆棧跟蹤:

java.io.EOFException 
    at java.io.DataInputStream.readUnsignedShort(Unknown Source) 
    at java.io.DataInputStream.readUTF(Unknown Source) 
    at java.io.DataInputStream.readUTF(Unknown Source) 
    at ClientConnection.receiveFile(ClientConnection.java:80) 
    at ClientConnection.run(ClientConnection.java:46) 
    at java.lang.Thread.run(Unknown Source) 

1 
Accepted connection : Socket[addr=/127.0.0.1,port=60653,localport=4444] 
File LF-statistikkboka(Myers).pdf received from client. 
1 
java.io.EOFException 
    at java.io.DataInputStream.readUnsignedShort(Unknown Source) 
    at java.io.DataInputStream.readUTF(Unknown Source) 
    at java.io.DataInputStream.readUTF(Unknown Source) 
    at ClientConnection.receiveFile(ClientConnection.java:80) 
    at ClientConnection.run(ClientConnection.java:46) 
    at java.lang.Thread.run(Unknown Source) 

File WHAT IS LEFT TO DO.docx received from client. 

按照要求的代碼,從客戶端接收命令

in = new BufferedReader(new InputStreamReader(
       clientSocket.getInputStream())); 
     String clientSelection; 
     clientSelection = in.readLine(); 
     System.out.println(clientSelection); 
     while ((clientSelection) != null) { 
      switch (clientSelection) { 
      case "1": 
       receiveFile(); 
       break; 
      case "2": 
       String outGoingFileName; 
       while ((outGoingFileName = in.readLine()) != null) { 
        sendFile(outGoingFileName); 
       } 
       break; 
      case "3": 
       sync(); 
       break; 
      default: 
       System.out.println("Incorrect command received."); 
       break; 
      } 
      //in.close(); 
      break; 
     } 
+0

請顯示服務器代碼 - 畢竟,這是錯誤的地方,對吧? –

+0

完成。這就是接收文件並將錯誤吐出的功能。 –

+0

哪些調用拋出異常? (什麼是堆棧跟蹤?) –

回答

0

罪魁禍首可能是客戶端代碼中的幾行:

PrintStream oos = new PrintStream(sok.getOutputStream()); 
oos.println("1"); 

字符串「1」將通過連接發送,但沒有服務器代碼來接收它,因此它與文件名稱混淆,文件名稱被解釋爲大小,文件數據爲太短,所以你會得到很多例外。由於該值是一個常量,因此在傳輸字符串「1」時似乎沒有意義,因此刪除這些行應該至少可以修復它的一部分。

+0

這部分工作,它是在代碼的另一部分,所做的只是它的一個命令,所以它可以準備服務器接收文件 –

+0

我希望看到接收該「1」的代碼。問題可能在那裏。 – tbodt

0

您必須用BufferedReader讀取'1'行,這會'偷'下面的一些數據。您應該使用DataInputStream.readUTF()從流中讀取命令,使用相同的DataInputStream讀取以下文件,並且應該使用DataOutputStream.writeUTF()編寫該命令,使用您用來發送命令的DataOutputStream文件。

注意不需要將整個文件讀入內存。它只是浪費了內存,增加了延遲,並沒有擴展。使用像你的接收循環一樣的複製循環,以及一個8k的緩衝區。

+0

當我嘗試讀取utF時,會掛起服務器 –

相關問題