0

我正在开发客户端和服务器之间的简单文件传输应用程序。这是我的代码:我的客户(发件人):

try{
                File file_sender=XMLParser.register(peername, address, port, listfile);
                int count;
                byte[] buffer = new byte[1024];
                int len=(int) file_sender.length();
                byte[] mybytearray = new byte[len];     
                DataOutputStream output=new DataOutputStream(Info.connection.getOutputStream());
                output.writeInt(len);
                System.out.println(len);
                BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file_sender));
                bis.read(mybytearray, 0, len);
                output.write(mybytearray, 0, len);
                bis.close();
                output.close();
               // Info.connection.close();
            }catch(Exception ex){
                System.out.println(ex.toString());
            }

我的服务器(接收方):

public class IOThread extends Thread {
private Socket connection;
private DataInputStream input;
public IOThread(Socket connection) throws IOException{
    this.connection=connection;
    input=new DataInputStream(connection.getInputStream());

}
@Override
public void run(){
    while(true){
        try{
            int filesize=12022386;
            int bytesRead;
            int currentTot = 0;
            byte[] bytearray = new byte [filesize];
            int len=input.readInt();
            FileOutputStream fos = new FileOutputStream("data.xml");
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            bytesRead=input.read(bytearray, 0,bytearray.length);
            System.out.println(len);
            currentTot=bytesRead;
            do{
                bytesRead=input.read(bytearray, currentTot, (bytearray.length-currentTot));
                if(bytesRead>=0) currentTot+=bytesRead;
                System.out.println("pos: "+currentTot);
            } while(len!=currentTot);
            bos.write(bytearray, 0, currentTot);
            bos.close();
            //connection.close();
            System.out.println("Done");
        }catch(EOFException ex){
            System.out.println(ex.toString());
            break;
        }catch( Exception ex){}
    }
}

我想传输多个文件,所以我不想关闭套接字。因此,我使用变量“len”来检查文件是否完全传输。

如果我在发送文件后关闭“输出”,则服务器会抛出 EOFException 并且文件发送成功。

当我不关闭输出时,服务器无法接收文件成功。但是服务器不会抛出 EOFException。

你能帮我解决这个问题吗?更新:如果我不在客户端关闭变量“输出”,这是我在控制台屏幕上的输出:

246

位置:496

谢谢。 对不起我的英语不好

4

4 回答 4

2

两件事情:

首先,您似乎忽略了接收代码中的文件长度?你有:

        int filesize=12022386;
        int bytesRead;
        int currentTot = 0;
        byte[] bytearray = new byte [filesize];
        int len=input.readInt();

无论 的值如何,您都将 bytearray 的大小调整为 12022386 字节len,并且您正在从输入流中请求那么多字节。

其次,当您关闭输出流时,任何尚未写入的缓存/缓冲数据都会自动刷新(即,在您的情况下,发送到服务器)。

当您完成发送第一个文件以强制它完成将所有数据发送到服务器时,显式刷新输出流。然后,您可以继续将该输出流用于其他事情。

output.flush()传输完成后在您的发送代码中执行。

于 2013-10-28T12:40:49.610 回答
2

问题是您读取的文件超出了文件的大小,也就是说len,您读取的不是bytearray.length字节,而是更大的字节。

因此,您读取的不仅仅是len字节,因此len!=currentTot永远不会满足,因为从示例输出中可以看出,currentTot == 496并且len == 246.

在您的 while 循环中进行以下更改:

do{
   bytesRead=input.read(bytearray, currentTot, (len - currentTot));
   if(bytesRead>=0) currentTot += bytesRead;
   System.out.println("pos: " + currentTot);
} while(len != currentTot);

只是为了确保您不会因为类似的错误而陷入无限循环,您可以使用currentTot < len而不是len != currentTot作为您的条件。

此外,由于您已经在使用DataInputStream,请考虑使用readFully. 这会阻塞,直到从套接字读取给定数量的字节,基本上消除了对 while 循环的需要。在这里阅读更多。

于 2013-10-28T13:02:59.323 回答
2

发送文件后丢弃所有循环并使用DataInputStream.readFully();关闭套接字;不要结束文件长度;并使用正常大小的缓冲区,比如 8192 字节。

于 2013-10-28T23:11:50.470 回答
0

您的BufferedOutputStream填充似乎不正确。下面的代码必须在 while 循环内。

bos.write(bytearray, 0, currentTot);

尝试这样的事情:

BufferedOutputStream buffOut=new BufferedOutputStream(fos);
byte []arr = new byte [1024 * 1024];
int available  = -1;
while((available = buffIn.read(arr)) != -1) { 
    buffOut.write(arr, 0, available); 
}      
buffOut.flush();
buffOut.close(); 

并再次测试。

编辑:用@Jason 的正确评论更新了我的答案。

于 2013-10-28T12:29:16.217 回答