0

I have a problem sending files through socket java. Sometimes the code works, sometimes not. I test the while block in both, it seems the code is sending all the bytes, but the server is not receiving (but even in this test, the file is sent correctly). In this case, the server stopped receive data. All files are about 150Kb. I'm using the port 9191.

Server:

while (true) {
        try {
            Socket socket = ss.accept();
            ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
            String fileName = in.readUTF();

            FileOutputStream fos = new FileOutputStream(destinationPath + fileName);
            byte[] buf = new byte[1024];

            int len;
            while ((len = in.read(buf)) >= 0) {
                fos.write(buf, 0, len);
            }
            fos.flush();

        } catch (Exception ex) {
            ex.printStackTrace();
        }
}

Client:

    try {
        Socket socket = new Socket(host, port);
        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());

        out.writeUTF(file.getName());
        out.writeLong(file.length());
        FileInputStream in = new FileInputStream(file);
        byte[] buf = new byte[1024];

        int len;
        while ((len = in.read(buf)) >= 0) {
            out.write(buf, 0, len);
        }

        out.close();
        socket.close();

    } catch (Exception e) {
        throw e;
    }

2 Answers 2

1

First you should replace ObjectInputStream and ObjectOutputStream with DataInputStream and DataOutputStream respectively. You are not serializing java objects and it makes no sense to use stream classes meant for that purpose.

Second you are sending the file length in the client but not specifically reading it in the server. It is instead getting added to the beginning of the file.

Sign up to request clarification or add additional context in comments.

7 Comments

I made the changes and realize that it send 1 file, and the second (the same or different) file the code on server goes to a infinite loop in "while ((len = in.read(buf)) >= 0) {", because I put a println after the block and it never shows in second time.
@Marcelo if you want to send multiple files from client to server, I would suggest first sending an int that tells the server how many files to expect. Then for each file start with the file name, followed by it's size, then by size bytes. On the server read in the file name, it's size then copy size bytes from the stream to the file and repeat until out of files.
In fact, in localhost works, but in a ubuntu server remotely doesn't. I clear iptables rules and nothing. In this case, I send one file, and after some seconds, another file.
What is the error you get when attempting it remotely?
Nothing. It stop internally in the while loop and does nothing. I put messages internally and suddenly it stop showing message
|
1

On the client you say,

out.writeUTF(file.getName());
out.writeLong(file.length());

But on the server you say,

String fileName = in.readUTF();
FileOutputStream fos = new FileOutputStream(destinationPath + fileName);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) >= 0) {
    fos.write(buf, 0, len);
}
fos.flush();

You didn't read the file length. And you need to make sure you read all of the sent bytes (or your file will be corrupt). Also, don't forget to close() the FileOutputStream (or use a try-with-resources to close it for you). Something like,

String fileName = in.readUTF();
try (FileOutputStream fos = new FileOutputStream(destinationPath
        + fileName)) {
    long size = in.readLong();
    byte[] buf = new byte[1024];
    long total = 0;
    int len;
    while ((len = in.read(buf)) >= 0) {
        fos.write(buf, 0, len);
        total += len;
    }
    if (total != size) {
        System.err.printf("Expected %d bytes, but received %d bytes%n",
                size, total);
    }
}

6 Comments

I made the changes and realize that it send 1 file, and the second (the same or different) file the code on server goes to a infinite loop in "while ((len = in.read(buf)) >= 0) {", because I put a println after the block and it never shows in second time.
Make sure you're sending another file... the code above sends 1 file (not multiple files - and the client posted calls socket.close();)
In fact, in localhost works, but in a ubuntu server remotely doesn't. I clear iptables rules and nothing. In this case, I send one file, and after some seconds, another file, calling the SocketClient again
What do you mean by calling the SocketClient again? Once you call socket.close() you can't use the socket without reconnecting. Similarly, once you call out.close() you can't use the OutputStream from socket.getOutputStream() without reconnecting (for the same reason).
So, I instantiate SocketClient each time I want to send a file. In this case I call SocketClient N times in a loop. I think it is not a problem call socket.close() in the SocketClient in this case.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.