1

我試圖實現通過socket基本通信後,我現在擁有的是:獲得「java.io.EOFException的」發送文件throught插座

  • 服務器啓動的監聽套接字,

    this.serverSocket_ = new ServerSocket(this.serverPort_); 
    clientSocket = this.serverSocket_.accept(); 
    
  • 客戶機連接,並且服務器開始單獨的線程與該客戶端來操作,

  • 兩個開口對象輸出和輸入流,

    out = new ObjectOutputStream(clientSocket_.getOutputStream()); 
    out.flush(); 
    in = new ObjectInputStream(clientSocket_.getInputStream()); 
    
  • 客戶端發送兩個I雙打,字符串和長超過該流(刷新前後每一個),

    out.writeObject(conf_); 
        out.flush(); 
        out.writeObject(supp_); 
        out.flush(); 
        out.writeObject(separator_); 
        out.flush(); 
        out.writeObject(new Long(dataFile_.length())); 
        out.flush(); 
    
  • 服務器通過先前打開的流成功地接收的那些對象,

    conf_ = (Double) in_.readObject(); 
    supp_ = (Double) in_.readObject(); 
    separator_ = (String) in_.readObject(); 
    fileSize_ = (Long) in_.readObject(); 
    
  • 現在是「硬的部分」,

  • 個客戶想要發送文件,以便將打開不同的輸出流(不是對象輸出流),併發送該文件,

    FileInputStream fis = new FileInputStream(dataFile_); 
    BufferedInputStream bis = new BufferedInputStream(fis); 
    OutputStream os = clientSocket_.getOutputStream(); 
    
    while (current < fileSize) { 
        bytesRead = bis.read(mybytearray, 0, mybytearray.length); 
        if (bytesRead >= 0) { 
         os.write(mybytearray, 0, mybytearray.length); 
         current += bytesRead; 
        } 
        progressBar_.setValue(current); 
        progressBar_.repaint(); 
    } 
    os.flush(); 
    
  • 服務器接收文件(也使用簡單的輸入流而不是ObjectInputStream的),

    int bytesRead; 
    int current = 0; 
    
    tmpFile_ = File.createTempFile("BasketAnalysis", "rec.dat"); 
    
    byte[] mybytearray = new byte[fileSize]; 
    InputStream is = clientSocket_.getInputStream(); 
    FileOutputStream fos = new FileOutputStream(tmpFile_); 
    BufferedOutputStream bos = new BufferedOutputStream(fos); 
    bytesRead = is.read(mybytearray, 0, mybytearray.length); 
    current = bytesRead; 
    
    do { 
        bytesRead = is.read(mybytearray, current, 
        (mybytearray.length - current)); 
        if (bytesRead >= 0) 
         current += bytesRead; 
    
    } while ((bytesRead > -1) && (current < fileSize)); 
    
    bos.write(mybytearray, 0, current); 
    bos.flush(); 
    bos.close(); 
    
  • 到目前爲止一切正常,文件被接收,但現在服務器執行一段時間,在該文件上消耗處理後發送響應與磨片結果客戶端,

    String resp = new String("Some processing result..."); 
    out_.writeObject(resp); 
    out_.flush(); 
    
  • 客戶端應該得到的結果是什麼完成整個通信,

    String message = (String) in.readObject(); 
    Console.info("server > " + message); 
    

不幸的是,在客戶端這最後一步失敗,出現異常:

java.io.EOFException 
     at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source) 
     at java.io.ObjectInputStream.readObject0(Unknown Source) 
     at java.io.ObjectInputStream.readObject(Unknown Source) 
     at basketAnalysis.client.Client.run(Client.java:74) 
     at java.lang.Thread.run(Unknown Source) 

我想客戶端阻止在發送文件後等待服務器響應,但在發送文件後突然完成異常。我很確定我在切換簡單流和對象流時做了錯誤的事情。

有沒有人知道我應該改變它的工作方式?

預先感謝您!

+0

當你out_.writeObject(resp);'爲最後的消息時,你沒有得到服務器端的異常嗎? – Mat

+0

沒有。實際上,服務器並未完成處理,因爲客戶端會斷開導致服務器端異常的原因。 – WojtusJ

回答

3

我覺得你的基本的誤解是在這裏:

客戶要發送一個文件,以便打開不同的輸出流

OutputStream os = clientSocket_.getOutputStream(); 

這並不打開不同輸出流 - 這將得到另一個參考相同的輸出流,你已經包裝在ObjectOutputStream。如果你想要兩個數據流,你需要打開兩個獨立的連接。