java - 如何以适当的方式关闭OutputStream?

标签 java file-io client-server fileinputstream fileoutputstream

在我的客户端服务器应用程序中,它能够接收命令并返回结果。当我尝试从服务器端下载文件时出现问题。输入下载命令后,服务器提示显示此错误,

java.net.SocketException: socket closed

图片:

Image

否则编程工作正常,也可以将文件下载到客户端。

注意,我认为可能的原因是关闭了outputSteram(在我的服务器端项目中),这可能没有以正确的方式完成。

我完整的工作代码:

服务器端:

    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();//the problem probably occurs here.
                           // 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);
            }

        }
    }
}

客户端:

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

                        }

                        /*
                         while ((bytesReceived = is.read(buffer)) >=0) {
                         //while ((bytesReceived = is.read(buffer))>=buffer) {
                         fos.write(buffer, 0, bytesReceived);
                         }
                         */
                        request = "";
                        fos.close();
                        is.close();
                    }
                }
                System.out.print("\nType command: ");
                Connected = true;
            }
            outputToServer.close();
            inputFromServer.close();
            socket.close();
        } catch (IOException e) {
            System.err.println(e);
        }

    }
}

最佳答案

我认为问题在于,在处理该命令(GET)后,您将在该os.close()调用中关闭服务器套接字。请注意,os outputToClientinputFromClient 都依赖于同一个服务器套接字。因此,当关闭 os 时,您会影响其他两个流。然后,在提供 GET 请求后,服务器循环转到开头并尝试运行 inputFromClient.readLine() 但底层套接字已关闭。

关于java - 如何以适当的方式关闭OutputStream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30426988/

相关文章:

java - 图像在 ImageView 中不可见

java - 服务器遇到内部错误,异常是 org.apache.jasper.JasperException : Unable to compile class for JSP

c# - 如何从末尾截断文件 X 字节?

java - 本地运行的 hibernate 与服务器上运行的 hibernate 之间的同步

java - 尽管服务器已发送,客户端仍在等待服务器的回复

java - 其他电脑上的Netty连接超时

java - 对二维数组中的对象使用方法

java - 如何使用 https 将 spring-config-server 与 vertx 一起使用?

python - 为什么 python 不会追加到这个文件中?

java - android 内部存储写入文件后没有文件