使用Java套接字传输多个文件 - 断开管道异常

时间:2014-05-20 02:10:33

标签: java sockets tcp pipe

我一直在尝试编写一个使用Java套接字发送多个文件的客户端/服务器应用程序。我已经查看了与此相关的每个线程,我只是无法弄清楚为什么我写入套接字时发送文件的代码会抛出一个Broken Pipe异常。我真的可以使用一些帮助;我在阳光下试过各种方法,但我无法弄明白。

编辑 - 谢谢大家!下面的代码非常有效。

发件人代码:

long size;

dos.writeInt(fileArray.length);

//send every file in array
for (File fileArray1 : fileArray) {
    int bytesRead = 0;

    fis = new FileInputStream(fileArray1);

    //send filename                        
    dos.writeUTF(fileArray1.getName());

    //send file size (bytes)
    dos.writeLong(size = fileArray1.length());

    System.out.println("Size: " + size);

    //send file 
    try {
        while ((bytesRead = fis.read(buf)) != -1) {
            dos.write(buf, 0, bytesRead);
            publish(new Progress(null, (int) ((sentByteCount / totalByteCount) * 100)));
        }

        dos.flush();

    } catch (IOException ex) {
    System.out.println("ERROR!!!!");
    }

    //close file stream, has been sent at this point
    fis.close();

}

System.out.println("Done sending files");
dos.close();
clientSocket.close();

接收人代码:

while (true) {

    socket = serverSocket.accept();

    dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

    //get number of files being received
    numFiles = dis.readInt();

    //read all files
    for (int i = 0; i < numFiles; i++) {

        filename = dis.readUTF();
        System.out.println("Receiving " + filename);

        size = dis.readLong();

        file = new File(filename);               

        fos = new FileOutputStream(filename);

        long total = 0;
        int count = 0;       

        while ((total < size) && ((count = dis.read(buf, 0, (int) Math.min(buf.length, size - total))) > 0)){
            fos.write(buf, 0, count);
            total += count;
        }

        fos.close();

        System.out.println("Received file " + filename);

    }


    dis.close();

}//end while

2 个答案:

答案 0 :(得分:0)

接收器中的这一行有一个重要的返回值!

        dis.read(buf);

最有可能的是,您只想使用readFully()

此外,您不需要为接收器中的每次读取创建缓冲区,而是使用多参数读取方法。

答案 1 :(得分:0)

编辑后你的写循环仍然是错误的。您可以使用以下语句在文件末尾写入垃圾:

fos.write(buf);

编写该循环的正确方法如下:

long total = 0;
while (total < size && (count = in.read(buffer, 0, size-total > buffer.length ? buffer.length : (int)(size-total))) > 0)
{
    fos.write(buffer, 0, count);
    total += count;
}
fos.close();

这样你就不会在文件末尾写垃圾,也不需要DataInputStream

NB:

  • 不要冲洗内部循环。它彻底摧毁了缓冲点。
  • 你不需要这个:

    if (!file.exists())
        file.createNewFile();
    

调用new FileOutputStream()已经完成了所有这些。您只是重复操作系统已经完成的工作,无论如何它仍然会这样做。