Why fileOutputStream can't output any string after an empty line (or a line break) in client-server application?

自作多情 提交于 2019-12-02 16:43:21

问题


In my client-server application, when I try to download a file from the serverSide, the file gets downloaded; but the header information such as some additional text with line break can't be read. As you can see in my Server class this following information is supposed to be printed out in the client side.

outputToClient.printf("Status OK\r\nSize %d Bytes\r\n\r\nFile %s Download was successfully\r\n",
                                    fileSize, filename);

But it doesn't. Only the fisrt string (Status OK) before the \r\n gets printed, not any string after \r\n.

How can I fix it?

My complete code:

ServerSide:

    public class ServerSide {

    private BufferedReader inputFromClient;
    private PrintWriter outputToClient;
    private FileInputStream fis;
    private OutputStream os;
    private static final int PORT = 8000;
    private ServerSocket serverSocket;
    private Socket socket;

    public static void main(String[] args) {
        int port = PORT;
        if (args.length == 1) {
            port = Integer.parseInt(args[0]);
        }
        new ServerSide(port);
    }

    private boolean fileExists(File[] files, String filename) {
        boolean exists = false;
        for (File file : files) {
            if (filename.equals(file.getName())) {
                exists = true;
            }
        }
        return exists;
    }

    public ServerSide(int port) {
        // create a server socket
        try {
            serverSocket = new ServerSocket(port);
        } catch (IOException ex) {
            System.out.println("Error in server socket creation.");
            System.exit(1);
        }

        while (true) {
            try {

                socket = serverSocket.accept();
                 outputToClient = new PrintWriter(socket.getOutputStream());
                inputFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                while (true) {

                    String request = inputFromClient.readLine();

                    if (!request.startsWith("exit") && !request.startsWith("pwd") && !request.startsWith("list") && !request.startsWith("GET")) {
                        outputToClient.println("Wrong request\r\n"
                                + "\r\n");
                    } else if (request.startsWith("exit")) {
                        break;
                    } else if (request.startsWith("pwd")) {
                        File file = new File(System.getProperty("user.dir"));
                        outputToClient.print("Status OK\r\n"
                                + "Lines 1\r\n"
                                + "\r\n"
                                + "Working dir: " + file.getName() + "\r\n");
                    } else if (request.startsWith("list")) {
                        File file = new File(System.getProperty("user.dir"));
                        File[] files = file.listFiles();
                        outputToClient.print("Status OK\r\n"
                                + "Files " + files.length + "\r\n"
                                + "\r\n"
                                + Arrays.toString(files).substring(1, Arrays.toString(files).length() - 1) + "\r\n");
                    } else if (request.startsWith("GET")) {
                        String filename = request.substring(4);
                        File file = new File(System.getProperty("user.dir"));
                        File[] files = file.listFiles();

                        if (fileExists(files, filename)) {
                            file = new File(filename);
                            int fileSize = (int) file.length();

                            outputToClient.printf("Status OK\r\nSize %d Bytes\r\n\r\nFile %s Download was successfully\r\n",
                                    fileSize, filename);
                            outputToClient.flush();

                            try (FileInputStream fis = new FileInputStream(file)) {
                                os = socket.getOutputStream();
                                byte[] buffer = new byte[(1 << 7) - 1];
                                int bytesRead = 0;

                                while ((bytesRead = fis.read(buffer)) != -1) {
                                    os.write(buffer, 0, bytesRead);
                                }

                            }
                            //os.close();
                           // fis.close();
                        } else {
                            outputToClient.print("Status 400\r\n"
                                    + "File " + filename + " not found\r\n"
                                    + "\r\n");
                            outputToClient.flush();
                        }
                    }
                    outputToClient.flush();
                }
            } catch (IOException e) {
                System.err.println(e);
            }

        }
    }
}

ClientSide:

public class ClientSide {

private static Socket socket;
private static PrintWriter outputToServer;
private static BufferedReader inputFromServer;
private static InputStream is;
private static FileOutputStream fos;
private static final int PORT = 8000;
private static final String SERVER = "85.197.159.45";
boolean Connected;
DataInputStream serverInput;

public static void main(String[] args) throws InterruptedException {
    String server = "localhost";
    int port = PORT;

    if (args.length >= 1) {
        server = args[0];
    }
    if (args.length >= 2) {
        port = Integer.parseInt(args[1]);
    }

    new ClientSide(server, port);
}

public ClientSide(String server, int port) {

    try {
        socket = new Socket(server, port);
        serverInput = new DataInputStream(socket.getInputStream());
        outputToServer = new PrintWriter(socket.getOutputStream(), true);
        inputFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        System.out.println("Client is connected! ");
        Connected = true;
        String line = null;

        Scanner sc = new Scanner(System.in);
        System.out.print("Type command: ");

        while (sc.hasNextLine()) {
            String request = sc.nextLine();

            if (request.startsWith("exit")) {
                outputToServer.println(request);
                System.out.println("Application exited!");
                //outputToServer.flush();
                break;
            } else if (request.startsWith("pwd")) {
                outputToServer.println(request);
                outputToServer.flush();
            } else if (request.startsWith("list")) {
                outputToServer.println(request);
                outputToServer.flush();
            } else if (request.startsWith("GET")) {
                System.out.print("\r\n");
                outputToServer.println(request);
                outputToServer.flush();
            }
            while (Connected) {
                line = inputFromServer.readLine();
                System.out.println(line);
                if (line.isEmpty()) {
                    Connected = false;
                    if (inputFromServer.ready()) {
                        System.out.println(inputFromServer.readLine());
                    }
                }
                if (line.startsWith("Status 400")) {
                    while (!(line = inputFromServer.readLine()).isEmpty()) {
                        System.out.println(line);
                    }
                    break;
                }
                if (request.startsWith("GET")) {
                    File file = new File(request.substring(4));
                    is = socket.getInputStream();
                    fos = new FileOutputStream(file);

                    byte[] buffer = new byte[socket.getReceiveBufferSize()];
                    serverInput = new DataInputStream(socket.getInputStream());
                    //int bytesReceived = 0;
                    byte[] inputByte = new byte[4000];

                    int length;
                    while ((length = serverInput.read(inputByte, 0, inputByte.length)) > 0) {
                        fos.write(inputByte, 0, length);

                    }

                    request = "";
                    fos.close();

                }
            }
            System.out.print("\nType command: ");
            Connected = true;
        }
        outputToServer.close();
        inputFromServer.close();
        socket.close();
    } catch (IOException e) {
        System.err.println(e);
    }

}

}


回答1:


while (Connected) {
    line = inputFromServer.readLine();
    System.out.println(line);
    if (line.isEmpty()) {
        Connected = false;
        if (inputFromServer.ready()) {
            System.out.println(inputFromServer.readLine());
        }
    }
    // ...

Usual misuse of ready(). Try this:

while ((line = inputFromServer.readLine()) != null)
   System.out.println(line);
   if (line.isEmpty()) {
       Connected = false;
        break;
    }
    // ...

NB You don't need the fileExists() method at all, and you certainly don't need to write it like that. new FileInputStream() will throw FileNotFoundException if the file doesn't exist. Catch it.




回答2:


You should close the output stream outputToClient.close() in ServerSide after last outputToClient.flush()

In your client side you need to establish connection again, so move the connection part inside the loop.



来源:https://stackoverflow.com/questions/30429281/why-fileoutputstream-cant-output-any-string-after-an-empty-line-or-a-line-brea

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!