我不知道是不是我的思路有问题。目的是客户端从服务器端下载到某文件。服务器端ServerSocket启动后,客户端建立socket,客户端向流中写入消息类型,需要的文件名等等,然后从流中逐个字节开始读文件的字节(我认为这时流中没有东西客户端程序会暂时阻塞在这),服务器端识别出消息类型,将需要的文件逐个字节写入流。大概的代码如下客户端public void downloadFile(String groupName, String filePath, String fileName) {
try {
Socket socket = new Socket(serverIP, filePort);
InputStream is = socket.getInputStream();
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(new Integer(ClientToServerMessageType.DownloadFile));
oos.writeObject(new String(account));
oos.writeObject(new String(groupName));
oos.writeObject(new String(fileName));
oos.writeObject(new Long(0));
oos.flush();
File file = new File(filePath + fileName);
FileOutputStream dos = new FileOutputStream(file);
int temp; 
do {
temp = ois.read();
dos.write(temp);         //问题就在这,我发现卡在这个循环中,不能跳出,我认为服务器端将-1写进去了的,应该能跳出
}while(temp != -1);
dos.flush();
oos.close();
dos.close();
is.close();
JOptionPane.showMessageDialog(null, "文件下载成功");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
服务器端//前面的那些account,groupName等已经从流中无误地读出来了,这是向流中写文件的数据
private void provideFile(String groupName, String fileName, ObjectOutputStream oos) {
File file = new File(ServerFileSavePath.fileSavePath + "\\" + groupName + "\\" + fileName);
FileInputStream dis;
try {
dis = new FileInputStream(file);
int temp; 
do {
temp = dis.read();
oos.write(temp);
}while(temp != -1);
oos.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

解决方案 »

  1.   

    换这个试试do {
                    temp = ois.read();
                    if(temp ==-1)
                    {
                      break;
                    }
                    dos.write(temp);        
                }while(true);
      

  2.   

    你这样会把-1写进去,你要不换成这样试试
                dis = new FileInputStream(file);
                int temp =0; 
                while((temp=dis.read())!=-1){
                   oos.write(temp);
                   oos.flush();
                }
                
     
      

  3.   

    LZ 的 dis没关闭
    private void provideFile(String groupName, String fileName, ObjectOutputStream oos) {
            File file = new File(ServerFileSavePath.fileSavePath + "\\" + groupName + "\\" + fileName);
            FileInputStream dis
      

  4.   

    temp = dis.read();
    oos.write(temp);
    这两句有问题,temp=-1的时候,write(-1),在客户端读到的应该是255。
    所以不正确。
      

  5.   

    只有在服务器端关闭流之后,客户端才会认为到达了流的结尾。建议:
    1.服务器端写入完成后,关闭输出流
    2.如果不想关闭输出流,那么在写入文件前,先把文件的长度写进来,客户端先获取文件长度,然后根据这个长度来读取内容,而不是依赖于流的结束
    另外:如楼上所说,代码有很多逻辑错误。
          比如把最后一个-1错误的写入到了文件里
          再比如,服务器端构造ObjectOutputStream时会往底层的字节流里写入一些内容,
                  如果客户端没有使用对应的ObjectInputStream读的话,则会把这些信息错误的当作文件的开头部分。
      

  6.   

    导致客户端read()阻塞的问题在于服务器端没有关闭输出流另外,逻辑上有很多程序错误。
      

  7.   

    6L一语中的。看了大家的回帖,我再修改之后,问题解决了。我错在对-1的理解吧,-1是流结束标识,不能通过向流中写入-1再读出-1确认读取结束,然后用LS几种写法都是可以的,6L提到的流的类型不一致也是个问题。真的谢谢各位了!