2

Ok so I have a block of code that is supposed to send multiple files over a socket. The way I am doing this in a for loop I am opening a socket -> transferring a file -> closing socket then repeat for other files. The said code it below:

for (int i = 0; i < fname.size(); i++) {
            Socket sok = new Socket("localhost",4444);
            PrintStream oos = new PrintStream(sok.getOutputStream());
            oos.println("1");
            try {

                System.out.println(fname.get(i));
                File myFile = new File(path+fname.get(i));
                byte[] mybytearray = new byte[(int) myFile.length()];

                FileInputStream fis = new FileInputStream(myFile);
                BufferedInputStream bis = new BufferedInputStream(fis);
                // bis.read(mybytearray, 0, mybytearray.length);

                DataInputStream dis = new DataInputStream(bis);
                dis.readFully(mybytearray, 0, mybytearray.length);

                OutputStream os = sok.getOutputStream();

                // Sending file name and file size to the server
                DataOutputStream doss = new DataOutputStream(os);
                doss.writeUTF(myFile.getName());
                doss.writeLong(mybytearray.length);
                doss.write(mybytearray, 0, mybytearray.length);
                doss.flush();
                sok.close();
                System.out.println("File " + fname.get(i) + " sent to Server.");

            } catch (Exception e) {
                System.err.println("File does not exist! (May not be true)   Generated Error: "+e);
            } 


            //sendFile(path+fname.get(i));
            //sock.close();
        }
    } catch (Exception e) {
        System.err.println(e);
    }

Now what happens is the client doesn't spit out any errors, matter of fact, it actually says the files were sent to the server. Now the server spits out random errors. Sometimes the server receives some files (never all of them) and sometimes it receives no files and the errors that come out are random as well. The errors are one or a combination of the following:

java.io.EOFException
java.io.FileNotFoundException
java.net.SocketException: Connection reset
java.io.UTFDataFormatException

All those errors are on the Server side while trying to transfer. I am not sure what is going on here =/

SERVER CODE:

public void receiveFile() {


    try {
        int bytesRead;

        DataInputStream clientData = new DataInputStream(
                clientSocket.getInputStream());

        String fileName = clientData.readUTF();
        OutputStream output = new FileOutputStream((fileName));
        long size = clientData.readLong();
        byte[] buffer = new byte[100000];
        while (size > 0
                && (bytesRead = clientData.read(buffer, 0,
                        (int) Math.min(buffer.length, size))) != -1) {
            output.write(buffer, 0, bytesRead);
            size -= bytesRead;
        }

        output.close();
        clientData.close();

        System.out.println("File " + fileName + " received from client.");
    } catch (IOException ex) {
        System.err.println("Client error. Connection closed.     " +ex);
    }
}

Stacktrace:

java.io.EOFException
    at java.io.DataInputStream.readUnsignedShort(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at ClientConnection.receiveFile(ClientConnection.java:80)
    at ClientConnection.run(ClientConnection.java:46)
    at java.lang.Thread.run(Unknown Source)

1
Accepted connection : Socket[addr=/127.0.0.1,port=60653,localport=4444]
File LF-statistikkboka(Myers).pdf received from client.
1
java.io.EOFException
    at java.io.DataInputStream.readUnsignedShort(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at ClientConnection.receiveFile(ClientConnection.java:80)
    at ClientConnection.run(ClientConnection.java:46)
    at java.lang.Thread.run(Unknown Source)

File WHAT IS LEFT TO DO.docx received from client.

As requested the code for receiving commands from the client

in = new BufferedReader(new InputStreamReader(
                clientSocket.getInputStream()));
        String clientSelection;
        clientSelection = in.readLine();
        System.out.println(clientSelection);
        while ((clientSelection) != null) {
            switch (clientSelection) {
            case "1":
                receiveFile();
                break;
            case "2":
                String outGoingFileName;
                while ((outGoingFileName = in.readLine()) != null) {
                    sendFile(outGoingFileName);
                }
                break;
            case "3":
                sync();
                break;
            default:
                System.out.println("Incorrect command received.");
                break;
            }
            //in.close();
            break;
        }
Shamikul Amin
  • 169
  • 13

2 Answers2

0

The culprit probably is a few lines in the client code:

PrintStream oos = new PrintStream(sok.getOutputStream());
oos.println("1");

The string "1" will get sent over the connection, but there is no server code to receive it, so it gets confused with the file's name and the file's name is interpreted as the size and the file data is too short, so you get a lot of exceptions. Since the value is a constant, there seems to be no point in transmitting the string "1", so removing those lines should at least fix part of it.

tbodt
  • 16,609
  • 6
  • 58
  • 83
  • That part works, it is in another part of the code, all that does is that its a command so it can prep the server for receiving a file – Shamikul Amin Apr 24 '14 at 19:45
  • I would like to see the code that receives that "1". The problem could be there. – tbodt Apr 24 '14 at 19:45
0

You must be reading the '1' line with a BufferedReader, which will 'steal' some of the following data. You should use DataInputStream.readUTF() to read commands from the stream, with the same DataInputStream you use to read the following file, and you should use DataOutputStream.writeUTF() to write the command, using the same DataOutputStream you use to send the file.

NB there's no need to read the entire file into memory. It just wastes memory, adds latency, and doesn't scale. Use a copy loop like your receive loop, and a buffer of say 8k.

user207421
  • 305,947
  • 44
  • 307
  • 483