2011-04-26 102 views
0

我有一個服務器和多個客戶端,我試圖讓服務器線程同時向所有連接的客戶端發送一個文件。奇怪的是,有時文件被正確寫入有時筆記本電腦會發出噪音,文件被寫入控制檯,並且不會創建任何文件。我不會在兩次試驗之間對代碼進行任何更改。任何人都可以幫我解決這個問題嗎?由於在advance.Here發送服務器線程代碼服務器發送文件給客戶端java

try 
{ 
    out.println("AcceptFile,"); 
    FileInputStream fis = new FileInputStream(fn); 
    byte[] buffer = new byte[fis.available()]; 
    fis.read(buffer); 
    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()) ; 
    oos.writeObject(buffer); 
    oos.flush(); 
} 
catch(Exception c) 
{ 
    System.err.println("exc" + c); 
} 

這裏是客戶端線程接收

try 
{ 
    ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
        byte[] buffer = (byte[])ois.readObject(); 
        String pic="copy"+studId+".pdf"; 
        System.out.println(pic); 
        FileOutputStream fos = new FileOutputStream(pic); 
        fos.write(buffer); 
        fos.flush(); 
        fos.close();  
} 
catch(Exception e) 
{ 
    System.out.println("Exception writing"); 
} 

回答

2

這是一個反覆出現的問題,我看到了個遍。您不保證底層套接字在您不需要時不會刷新。如果是這樣,那麼客戶端可以得到一個部分對象,而ObjectInputStream將拋出一個異常。

處理它的方法是讓服務器通過ByteArrayOutputStream將Object寫入中間字節[]。然後發送一個簡單的頭文件,描述要遵循的字節長度,後面是字節[]的內容(在每次寫入後清空)。在客戶端,你做了與此相反的事情:讀取簡單的頭文件,以便知道需要多少字節,然後通過ByteArrayInputStream讀入byte [],然後從中讀入ObjectInputStream。當然,由於您只是寫入文件,所以您可以跳過客戶端的ObjectInputStream,並直接將byte []寫入文件。

import java.io.*; 

public class junk extends ClassLoader { 


    public static void main(String[] args) throws Exception { 
    new junk(); 
    } 

    public void marshal(OutputStream socketOutputStream, Object obj) 
    throws Exception 
    { 

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    ObjectOutputStream oos = new ObjectOutputStream(bos); 

    oos.writeObject(obj); 

    byte[] bytes = bos.toByteArray(); 

    DataOutputStream dos = new DataOutputStream(socketOutputStream); 

    // header 
    dos.writeInt(bytes.length); 
    dos.flush(); 

    dos.write(bytes); 
    dos.flush(); 
    } 

    public Object unmarshal(InputStream socketInputStream) throws Exception { 

    DataInputStream dis = new DataInputStream(socketInputStream); 

    int numToRead = dis.readInt(); 

    byte[] bytes = new byte[numToRead]; 

    dis.readFully(bytes); 

    ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 

    ObjectInputStream ois = new ObjectInputStream(bis); 

    return ois.readObject(); 

    } 

} 
+0

而在客戶端閱讀方面,您還需要滿足拆分數據包,因此您需要繼續閱讀,直到您閱讀了numToRead字節爲止。 – alpian 2011-04-26 23:36:00

+0

@ user726092我已經嘗試過,但用小的改變來創建文件,但它不工作。這裏是客戶端'\t DataInputStream dis = new DataInputStream(socket.getInputStream()); int numToRead = dis.readInt(); ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); ois.readObject(); String pic =「copy」+ studId + 「.pdf」; System.out.println(pic); FileOutputStream fos = new FileOutputStream(pic); fos.write(bytes); \t fos.flush(); fos.close();' – 2011-04-26 23:41:45

+0

和服務器端'out.println(「AcceptFile,」); \t \t \t ByteArrayOutputStream bos = new ByteArrayOutputStream(); \t \t ObjectOutputStream oos = new ObjectOutputStream(bos); \t \t oos.writeObject((Object)fn); \t \t \t \t byte [] bytes = bos.toByteArray(); \t \t \t \t DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); \t \t \t // \t頭 \t \t dos.writeInt(bytes.length); \t \t dos.flush(); \t \t \t \t dos.write(bytes); \t \t dos.flush();' – 2011-04-26 23:42:37

相關問題