Skip to content
Advertisement

Java read bytes from Socket on Linux

I’m trying to send a file from my Windows machine to my Raspberry-Pi 2, and I have a client and a server. The client should be able to send a zip file over the network to my server on my linux machine. I know my client and server work on Windows, as when I run both the client and server on windows and connect using 127.0.0.1 it works perfectly. But when sending it to my Pi, nothing gets sent over the socket. Any suggestion?

Server:
    package zipsd;

    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.ServerSocket;
    import java.net.Socket;

    public class Main {
        public static void main(String[] args) throws Exception {
            if (args.length < 3)
                System.out.println("Usage: zipsd <port> <directory> <password>");
            else {
                int port = Integer.parseInt(args[0]);
                String directory = args[1];
                String password = args[2];

                System.out.println("zipsd: starting server on port " + port);
                System.out.println("zipsd: directory = " + directory);

                ServerSocket ss = new ServerSocket(port);

                System.out.println("zipsd: listening...");

                while (true) {
                    try {
                        Socket client = ss.accept();

                        System.out
                                .println("zipsd: from " + client.getInetAddress());

                        InputStream input = client.getInputStream();
                        BufferedReader in = new BufferedReader(
                                new InputStreamReader(input));
                        PrintStream out = new PrintStream(client.getOutputStream());

                        String pwdAttempt = in.readLine();

                        if (pwdAttempt != null) {

                            if (!pwdAttempt.equals(password)) {
                                out.println("[SERVER] zipsd: invalid password");
                            } else {
                                out.println("[SERVER] zipsd: authenticated");

                                String zipName = in.readLine();
                                if (zipName != null) {
                                    File zipFile = new File(directory + "/"
                                            + zipName);

                                    try {
                                        FileOutputStream fos = new FileOutputStream(
                                                zipFile);
                                        BufferedOutputStream bos = new BufferedOutputStream(
                                                fos);

                                        byte[] data = new byte[1024 * 1024 * 50];
                                        int count;

                                        while((count = input.read(data)) > 0)
                                            bos.write(data, 0, count);

                                        for(int i = 0; i < 200; i++) //to see if data gets sent, it just prints 0's :(
                                            System.out.println(data[i]);


                                        System.out.println("Got zip file " + zipName);


                                        bos.flush();
                                        fos.close();
                                        bos.close();

                                        out.close();
                                        in.close();

                                        client.close();
                                    } catch (Exception e) {
                                        out.println("[SERVER] zipsd: error in transfer.");
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }



Client:

    package zipsend;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.nio.file.Files;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Main {

    public static class ZipUtils {

        public static void zipFolder(final File folder, final File zipFile)
                throws IOException {
            zipFolder(folder, new FileOutputStream(zipFile));
        }

        public static void zipFolder(final File folder,
                final OutputStream outputStream) throws IOException {
            try (ZipOutputStream zipOutputStream = new ZipOutputStream(
                    outputStream)) {
                processFolder(folder, zipOutputStream, folder.getPath()
                        .length() + 1);

                zipOutputStream.flush();
                zipOutputStream.finish();
                zipOutputStream.close();
            }
        }

        private static void processFolder(final File folder,
                final ZipOutputStream zipOutputStream, final int prefixLength)
                throws IOException {
            for (final File file : folder.listFiles()) {
                if (file.isFile()) {
                    final ZipEntry zipEntry = new ZipEntry(file.getPath()
                            .substring(prefixLength));
                    zipOutputStream.putNextEntry(zipEntry);
                    try (FileInputStream inputStream = new FileInputStream(file)) {
                        byte[] buf = new byte[(int) file.length() + 1];
                        int read = 0;
                        while ((read = inputStream.read(buf)) != -1) {
                            zipOutputStream.write(buf, 0, read);
                        }
                    }

                    zipOutputStream.flush();
                    zipOutputStream.closeEntry();
                } else if (file.isDirectory()) {
                    processFolder(file, zipOutputStream, prefixLength);
                }
            }
        }
    }



    public static void main(String[] args) throws Exception {
        if(args.length < 4)
            System.out.println("Usage: zipsend <folder> <ip> <port> <password>");
        else {
            String toZip = args[0];
            String ip = args[1];
            int port = Integer.parseInt(args[2]);
            String pwd = args[3];

            File folderToZip = new File(toZip);
            if(!folderToZip.exists()) {
                System.out.println("[ERROR] invalid folder name");
                System.exit(1);
            }

            System.out.print("[INFO] connecting... ");

            Socket s = new Socket(ip, port);

            System.out.println("OK.");
            System.out.println("[INFO] authenticating... ");

            BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            PrintStream out = new PrintStream(s.getOutputStream());

            out.println(pwd);
            System.out.println(in.readLine());


            System.out.println();
            System.out.print("[INFO] zipping " + toZip + "... ");

            File zipFile = new File(System.getProperty("user.dir") + "\" +  folderToZip.getName() + ".zip");

            ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zipFile));
            ZipUtils.processFolder(folderToZip, zout, folderToZip.getPath().length() + 1);
            zout.close();

            System.out.println("OK.");

            //Transfer file


            out.println(zipFile.getName());

            byte[] data = new byte[(int)zipFile.length()];
            FileInputStream fis = new FileInputStream(zipFile);
            BufferedInputStream bis = new BufferedInputStream(fis);

            System.out.println("[INFO] sending zip file... ");
            OutputStream os = s.getOutputStream();

            int count;
            while((count = bis.read(data)) > 0) {
                os.write(data, 0, count);
            }

            os.flush();
            os.close();
            fis.close();
            bis.close();
            s.close();

            System.out.println("[INFO] done. Sent " + Files.size(zipFile.toPath()) + " bytes.");

            zipFile.delete();
        }
    }
}

Advertisement

Answer

InputStream input = client.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(input));

Your problem is here. You can’t use multiple inputs on a socket when one or more of them is buffered. The buffered input stream/reader will read-ahead and ‘steal’ data from the other stream. You need to change your protocol so you can use the same stream for the life of the socket at both ends. For example, use DataInputStream, with readUTF() for the file name and read() for the data: at the sender, use DataOutputStream, with writeUTF() for the filename and write() for the data.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement