Sending a file with Java Sockets, losing data

0x5453

I'm trying to send a file from a client to a server with Sockets in Java. It works fine when I am testing on the same machine, but when I test across different machines, I lose large chunks of data, resulting in a corrupted file. If I try to send a very small file (<20 bytes), it doesn't even reach the println inside the server's while loop.

Here is my code:

Server.java

package edu.mst.cs.sensorreceiver;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    private static final int PORT = 51111;
    private static final int CHUNK_SIZE = 1024;
    private static final File _downloadDir = new File("downloads/");

    public static void main(String[] args) {
        if (!_downloadDir.exists()) {
            if (!_downloadDir.mkdirs()) {
                System.err.println("Error: Could not create download directory");
            }
        }

        Socket socket = null;
        try {
            ServerSocket server = new ServerSocket(PORT);

            while (true) {
                System.out.println("Waiting for connection...");
                socket = server.accept();

                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                String name = in.readLine();
                File file = new File(_downloadDir, name);

                String size = in.readLine();
                int fileSize;
                try {
                    fileSize = Integer.parseInt(size);
                } catch (NumberFormatException e) {
                    System.err.println("Error: Malformed file size:" + size);
                    e.printStackTrace();
                    return;
                }

                System.out.println("Saving " + file + " from user... (" + fileSize + " bytes)");
                saveFile(file, socket.getInputStream());
                System.out.println("Finished downloading " + file + " from user.");
                if (file.length() != fileSize) {
                    System.err.println("Error: file incomplete");
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void saveFile(File file, InputStream inStream) {
        FileOutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream(file);

            byte[] buffer = new byte[CHUNK_SIZE];
            int bytesRead;
            int pos = 0;
            while ((bytesRead = inStream.read(buffer, 0, CHUNK_SIZE)) >= 0) {
                pos += bytesRead;
                System.out.println(pos + " bytes (" + bytesRead + " bytes read)");
                fileOut.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileOut != null) {
                try {
                    fileOut.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("Finished, filesize = " + file.length());
    }
}

Client.java

package edu.mst.cs.sensorreceiver;

import java.io.*;
import java.net.Socket;

public class Client {
    private static final String HOSTNAME = "131.151.163.153";
    private static final int PORT = 51111;
    private static final int CHUNK_SIZE = 1024;

    public static void main(String[] args) {
        sendFile(args[0]);
    }

    private static void sendFile(String path) {
        if (path == null) {
            throw new NullPointerException("Path is null");
        }

        File file = new File(path);
        Socket socket = null;
        try {
            System.out.println("Connecting to server...");
            socket = new Socket(HOSTNAME, PORT);
            System.out.println("Connected to server at " + socket.getInetAddress());

            PrintStream out = new PrintStream(socket.getOutputStream(), true);

            out.println(file.getName());
            out.println(file.length());

            System.out.println("Sending " + file.getName() + " (" + file.length() + " bytes) to server...");
            writeFile(file, socket.getOutputStream());
            System.out.println("Finished sending " + file.getName() + " to server");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void writeFile(File file, OutputStream outStream) {
        FileInputStream reader = null;
        try {
            reader = new FileInputStream(file);
            byte[] buffer = new byte[CHUNK_SIZE];
            int pos = 0;
            int bytesRead;
            while ((bytesRead = reader.read(buffer, 0, CHUNK_SIZE)) >= 0) {
                outStream.write(buffer, 0, bytesRead);
                outStream.flush();
                pos += bytesRead;
                System.out.println(pos + " bytes (" + bytesRead + " bytes read)");
            }
        } catch (IndexOutOfBoundsException e) {
            System.err.println("Error while reading file");
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("Error while writing " + file.toString() + " to output stream");
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

I've been working on this for hours and I have made almost no progress. I thought I had a pretty good understanding of how reading/writing from streams works, but clearly I'm missing something here.

Again, everything works perfectly when I am sending and receiving from the same machine. But if I try to send a file between two computers, even if the two are on the same LAN, I lose a lot of the data that was sent.

Can anybody figure out my problem? I've already tried everything I could think of.

Elliott Frisch

You appear to be mixing chunked data and line oriented operation. I suggest you use a DataInputStream on the server, and a DataOutputStream. Starting on the client, something like

private static void sendFile(String path) {
    if (path == null) {
        throw new NullPointerException("Path is null");
    }

    File file = new File(path);
    Socket socket = null;
    try {
        System.out.println("Connecting to server...");
        socket = new Socket(HOSTNAME, PORT);
        System.out.println("Connected to server at "
                + socket.getInetAddress());

        try (DataOutputStream dos = new DataOutputStream(
                new BufferedOutputStream(socket.getOutputStream()));) {
            dos.writeUTF(file.getName());
            dos.writeLong(file.length());

            System.out.println("Sending " + file.getName() + " ("
                    + file.length() + " bytes) to server...");
            writeFile(file, dos);
            System.out.println("Finished sending " + file.getName()
                    + " to server");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Then on the server

socket = server.accept();

DataInputStream dis = new DataInputStream(socket.getInputStream());
String name = dis.readUTF();
File file = new File(_downloadDir, name);
long fileSize = dis.readLong();
System.out.println("Saving " + file + " from user... ("
        + fileSize + " bytes)");

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Java sending and receiving file over sockets

From Dev

Java Sockets - Sending data from client to server

From Dev

Sending binary data multiple times using Sockets in Java/Android

From Dev

Sockets data sending C# and Java - Overally & Specifically

From Dev

Sockets data sending C# and Java - Overally & Specifically

From Dev

Sending data through UDP sockets

From Dev

Sending Sockets with binary and ascii data

From Dev

Sending objects via java sockets

From Dev

Java sockets not sending/receiving messages

From Dev

Sending data from java to php file

From Dev

Sending a file over TCP sockets in Python

From Dev

How are sockets sending data through packets in erlang?

From Dev

Sending binary data over sockets with Python

From Dev

Sockets,BufferedWriter.flush() not sending the data

From Dev

sending and recieving data through sockets in the same activity

From Dev

Sending various types of data through sockets in Python

From Dev

Sending and receiving data through sockets and ports

From Dev

sending and recieving data through sockets in the same activity

From Dev

Python 3 sockets app stops sending data

From Dev

Sending data over sockets is slower with concurrent threads?

From Dev

Sending ByteArray using Java Sockets (Android programming)

From Dev

Java Sockets sending multiple objects to the same server

From Dev

Iterator seems to be losing data java

From Dev

Iterator seems to be losing data java

From Dev

Java Web Server: Not sending data when requesting an existing file

From Dev

Sending Txt file to server from client using python sockets

From Dev

JAVA file sending system

From Dev

What is the proper way of sending a large amount of data over sockets in Python?

From Dev

Java Socket Sending Data

Related Related

  1. 1

    Java sending and receiving file over sockets

  2. 2

    Java Sockets - Sending data from client to server

  3. 3

    Sending binary data multiple times using Sockets in Java/Android

  4. 4

    Sockets data sending C# and Java - Overally & Specifically

  5. 5

    Sockets data sending C# and Java - Overally & Specifically

  6. 6

    Sending data through UDP sockets

  7. 7

    Sending Sockets with binary and ascii data

  8. 8

    Sending objects via java sockets

  9. 9

    Java sockets not sending/receiving messages

  10. 10

    Sending data from java to php file

  11. 11

    Sending a file over TCP sockets in Python

  12. 12

    How are sockets sending data through packets in erlang?

  13. 13

    Sending binary data over sockets with Python

  14. 14

    Sockets,BufferedWriter.flush() not sending the data

  15. 15

    sending and recieving data through sockets in the same activity

  16. 16

    Sending various types of data through sockets in Python

  17. 17

    Sending and receiving data through sockets and ports

  18. 18

    sending and recieving data through sockets in the same activity

  19. 19

    Python 3 sockets app stops sending data

  20. 20

    Sending data over sockets is slower with concurrent threads?

  21. 21

    Sending ByteArray using Java Sockets (Android programming)

  22. 22

    Java Sockets sending multiple objects to the same server

  23. 23

    Iterator seems to be losing data java

  24. 24

    Iterator seems to be losing data java

  25. 25

    Java Web Server: Not sending data when requesting an existing file

  26. 26

    Sending Txt file to server from client using python sockets

  27. 27

    JAVA file sending system

  28. 28

    What is the proper way of sending a large amount of data over sockets in Python?

  29. 29

    Java Socket Sending Data

HotTag

Archive