简体   繁体   中英

Transferring Multiple files using Java Sockets - Broken Pipe Exception

I've been trying to write a client/server app that sends multiple files using Java sockets. I've looked through what seems like every thread pertaining to this and I just can't figure out why my code for sending the file is throwing a Broken Pipe exception when I write to the socket. I could really use some help; I've tried every method under the sun and I can't figure it out.

EDIT - Thanks, everyone! The code below works perfectly.

Sender code:

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();

Receiver Code:

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

This line in the receiver has a return value which is important!

        dis.read(buf);

Most likely, you just want to use readFully() .

Also, you don't need to create a buffer for each read in the receiver, instead, using the multi-param read methods.

After the edit your write loop is still wrong. You're writing junk at the end of the file with this statement:

fos.write(buf);

A correct way to code that loop is as follows:

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();

That way you don't write junk at the end of the file, and you don't need the DataInputStream either.

NB:

  • Don't flush inside loops. It completely destroys the point of buffering.
  • You don't need this:

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

Calling new FileOutputStream() already does all that. You're just repeating work that the operating system already does, and it will still do it anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM