客户端套接字不会从服务器接收数据

Client socket will not receive data from server

我的问题是,在我的客户端中,dis.read() 正在返回 -1,导致它从未真正收到文件。我唯一能想到的是,因为我在这个部分之前使用了一个PrintWriter和一个BufferedReader,所以dis.read()认为已经收到了所有数据。

客户代码:

public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
    Socket client = new Socket(serverAddress, port);
    client.setSoTimeout(5000);
    PrintWriter out = new PrintWriter(client.getOutputStream(), true);
    BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));

    try {
        out.println("101|" + fileName + "\n");

        if (input.readLine().equals("201")) {
            int br;
            byte[] data = new byte[4096];

            DataInputStream dis = new DataInputStream(client.getInputStream());
            FileOutputStream fos = new FileOutputStream(fileOut);

            while ((br = dis.read(data, 0, data.length)) != -1){
                fos.write(data, 0, br);
            }

            fos.close();
            dis.close();
        }
    } catch (SocketTimeoutException ste) {
        ste.printStackTrace();
        client.close();
    }
}

服务器代码:

private void sendFile(String filename, Socket client) throws IOException {
    int br;
    byte[] data = new byte[4096];
    PrintWriter out = new PrintWriter(client.getOutputStream(), true);

    out.println("201\n");

    DataOutputStream dos = new DataOutputStream(client.getOutputStream());
    FileInputStream fis = new FileInputStream(MeshFS.properties.getProperty("repository") + filename);

    while ((br = fis.read(data, 0, data.length)) != -1) {
        dos.write(data, 0, br);
        dos.flush();
    }

    fis.close();
    dos.close();
}

private String receiveRequest(Socket client) {
    String requestPart;
    String requestFull = "";
    try {
        BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));

        while (((requestPart = input.readLine()) != null) && (requestFull.length() < 2048)) {
            if (requestPart.equals("")) break;
            requestFull = requestFull + requestPart;
        }

        return requestFull;
    } catch (IOException ioe) {
        return requestFull;
    }
}

private void processRequest(String request, Socket out) {

    if (request != null) {
        try {
            String[] requestParts = request.split("\|");
            if (requestParts[0].equals("101")) {            //101:Get file
                sendFile(requestParts[1], out);

            } else {
                badRequest(out, request);
            }
        } catch (Exception e) {
            badRequest(out, request);
            e.printStackTrace();
        }
    }
}

    public void run() {
        while (!Thread.interrupted()) {
            try {
                server.setSoTimeout(1000);
                Socket client = server.accept();
                client.setSoTimeout(timeout);
                processRequest(receiveRequest(client), client);
                client.close();
            } catch (SocketTimeoutException ste) {
            } catch (IOException io) {
                io.printStackTrace();
            }
        }
        System.out.println("Socket closed");
}

是否有我遗漏或忘记包含的内容?我是不是在冲洗什么东西还是没有清理什么东西?

好的,我想我发现错误了。我做了一些实验,发现 InputStream 的行为很奇怪,如果多个对象试图从它们读取。在您的情况下,很可能是您客户的 receiveFile 方法中的 BufferedReaderDataInputStream 通过尝试读取相同的 inputStream 导致问题。我建议使用 DataInputStream 来读取第一行,这样您就不必创建 BufferedReader。即使 DataInputStream.readLine() 方法已被弃用,它在您的情况下仍应表现良好。

我编辑了客户端 receiveFile 方法以使用 DataInputStream 读取第一行。希望有用!

public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
    Socket client = new Socket(serverAddress, port);
    client.setSoTimeout(5000);
    PrintWriter out = new PrintWriter(client.getOutputStream(), true);
    DataInputStream dis = new DataInputStream(client.getInputStream());

    try {
        out.println("101|" + fileName + "\n");

        if (dis.readLine().equals("201")) {
            int br;
            byte[] data = new byte[4096];

            FileOutputStream fos = new FileOutputStream(fileOut);

            while ((br = dis.read(data, 0, data.length)) != -1){
                fos.write(data, 0, br);
            }

            fos.close();
            dis.close();
        }
    } catch (SocketTimeoutException ste) {
        ste.printStackTrace();
        client.close();
    }
}