2011-04-26 124 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

相关问题