我有一个服务器和多个客户端,我正在尝试让服务器线程同时向所有连接的客户端发送文件。奇怪的是,有时文件写得正确,有时笔记本电脑发出噪音并且文件是在控制台中写的,没有创建文件。我不会在试验之间对代码进行任何更改。有人可以帮我解决这个问题吗?在此先感谢。这是发送服务器线程代码
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");
}
答案 0 :(得分:2)
这是我一遍又一遍看到的反复出现的问题。您不能保证底层套接字在您不希望它时不会刷新。如果是,则客户端可以获取部分Object,而ObjectInputStream将抛出异常。
处理它的方法是让服务器通过ByteArrayOutputStream将Object写入中间字节[]。然后发送一个简单的头,描述要跟随的字节长度,然后是byte []的内容(每次写入后刷新)。在客户端,你执行相反的操作:读取简单的头文件,以便知道预期的字节数,然后通过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();
}
}