linux - Java 从 Linux 上的 Socket 中读取字节

标签 linux windows sockets network-programming raspberry-pi

我正在尝试将文件从我的 Windows 机器发送到我的 Raspberry-Pi 2,并且我有一个客户端和一个服务器。客户端应该能够通过网络将 zip 文件发送到我的 linux 机器上的服务器。我知道我的客户端和服务器在 Windows 上工作,因为当我在 Windows 上同时运行客户端和服务器并使用 127.0.0.1 连接时,它工作得很好。但是当把它发送到我的 Pi 时,没有任何东西通过套接字发送。有什么建议吗?

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

最佳答案

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

你的问题就在这里。当其中一个或多个被缓冲时,您不能在套接字上使用多个输入。缓冲输入流/阅读器将预读并从其他流中“窃取”数据。您需要更改协议(protocol),以便在两端的套接字的生命周期内使用相同的流。例如,使用 DataInputStream,文件名使用 readUTF(),数据使用 read():在发送端,使用 DataOutputStream,文件名用writeUTF(),数据用write()

关于linux - Java 从 Linux 上的 Socket 中读取字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30836218/

相关文章:

java - 是否可以通过 tcp 套接字发送握手参数?

java - 使用 DatagramPacket 发送 0x04 - 类似于十六进制 char[] 数据

c - C语言多线程服务器设计

linux - 使用 awk 提取一列的一部分并保存到另一个文件中

windows - Windows CMD 和 Bash 中的长算术

c++ - RegSetValueEx 静默无法写入 HKLM

具有 URLConnection 的 Java 应用导致 "Too many open files"

linux - Linux 中的文件访问方法

windows - 打开对话框保留设置

ios - 如何使用套接字编程将 iOS Swift 应用程序连接到硬件设备?