Как исправить исключение Broken Pipe Socket (Java)? Где закрывается связь? - PullRequest
0 голосов
/ 29 октября 2019

Я работаю над многопоточным веб-сервером для школьного проекта. Я должен иметь возможность зайти на локальный хост в моем браузере и запросить 3 разных файла (.htm, .jpeg, .pdf). Тем не менее, когда я делаю это для файла .htm с изображением внутри него (2 запроса), в браузере появляется файл .htm, но я получаю много исключений из-за разрыва трубопровода для каждой записи, которую я пытаюсь выполнить на изображении (для назначения требуется)записывать 1024 байта за раз). Что-то явно не так с тем, как я это реализовал, но я не понимаю, где закрывается соединение, когда я пытаюсь записать второй файл?

Я пробовал несколько разных вещей, чтобы попытатьсяисправить это, включая цикл, при попытке прочитать поток ввода сокета, но я думаю, что это противоречит цели многопоточного сервера.

Сервер:

    while(true){
        try {
            sock = servSock.accept(); // Handles the connection
            // Connection received log
            System.out.println("Connection received: " + new Date().toString() + " at " + sock.getInetAddress() + sock.getPort());
            HTTP pro = new HTTP(sock); // Client handler
            pro.run();

            ServerThread serverThread = new ServerThread(pro); 
            // Starts ServerThread
            serverThread.start();
        } catch (Exception e){
            System.out.println(e);
        }
    }

HTTP:


    public void run(){
        // Try to open reader
        try{
            readSock = new BufferedReader(new InputStreamReader(sock.getInputStream()));
        } catch (Exception e){
            System.out.println(e);
        }

        // Open output stream
        try{
            this.out = new DataOutputStream(sock.getOutputStream()); 
            this.printOut = new PrintWriter(sock.getOutputStream()); 
        } catch (Exception e){
            System.out.println(e);
        }

        // Try to read incoming line
        try {
            this.reqMes = readSock.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        StringTokenizer st = new StringTokenizer(reqMes);

        // Parse the request message
        int count = 0;
        while(st.hasMoreTokens()){
            String str = st.nextToken();
            if (count == 1){
                this.fileName = "." + str;
            }
            count += 1;
        }
        System.out.println("File name received.");

        File file = null;
        try {
            file = new File(this.fileName);
            this.f = new FileInputStream(file); // File input stream
            this.fileExists = true;
            System.out.println("File " + this.fileName +  " exists.");
        } catch (FileNotFoundException e) {
            System.out.println(e);
            this.fileExists = false;
            System.out.println("File does not exist.");
        }

        byte[] buffer = new byte[1024];
        // Write status line
        if (this.fileExists) {
            System.out.println("Trying to write data");
            try{
                this.out.writeBytes("HTTP/1.0 " + "200 OK " + this.CRLF);
                this.out.flush();
                this.printOut.println("HTTP/1.0 " + "200 OK " + this.CRLF);
                // Write Header
                this.out.writeBytes("Content-type: " + getMime(this.fileName) + this.CRLF);
                this.printOut.println("Content-type: " + getMime(this.fileName) + this.CRLF);
                this.out.flush();

                // Read file data
                byte[] fileData = new byte[1024];

                while (this.f.read(fileData) != -1) {
                    // Write File data
                    try{
                        this.out.write(fileData,0,1024);
                        this.out.flush(); // Flush output stream
                    } catch (IOException e) {
                        System.out.println(e);
                    }
                }
                System.out.println("Flushed");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

Для одного файла .htm в браузере файл и html выглядят нормально. Но похоже, что он делает второй запрос на файл .jpeg в html-файле, и браузер застревает при загрузке с java.net.SocketException: прерванный канал (ошибка записи) при записи данных каждый раз в

this.out.write(fileData,0,1024);

Спасибо, любая помощь приветствуется.

1 Ответ

0 голосов
/ 30 октября 2019

После долгих поисков среди разных проблем я нашел ответ здесь .

Проблема заключалась в неправильном форматировании заголовков ответов, что привело к преждевременному завершению соединения. Следующая пустая строка ("\ r \ n") должна быть отправлена ​​после заголовка.

Теперь работает следующий код (this.CRLF равен "\ r \ n"):

    public void run(){
        // Try to open reader
        try{
            readSock = new BufferedReader(new InputStreamReader(sock.getInputStream()));
        } catch (Exception e){
            System.out.println(e);
        }

        // Open output stream
        try{
            this.out = new DataOutputStream(sock.getOutputStream()); // Data output
            this.printOut = new PrintWriter(sock.getOutputStream()); // Print output
        } catch (Exception e){
            System.out.println(e);
        }

        // Try to read incoming line
        try {
            this.reqMes = readSock.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        StringTokenizer st = new StringTokenizer(reqMes);

        // Parse the request message
        int count = 0;
        while(st.hasMoreTokens()){
            String str = st.nextToken();
            if (count == 1){
                this.fileName = "." + str;
            }
            count += 1;
        }
        System.out.println("File name received.");

        // Initialize file to be sent
        File file = null;
        // Try to find file and create input stream
        try {
            file = new File(this.fileName);
            this.f = new FileInputStream(file); // File input stream
            this.fileExists = true;
            System.out.println("File " + this.fileName +  " exists.");
        } catch (FileNotFoundException e) {
            System.out.println(e);
            this.fileExists = false;
            System.out.println("File does not exist.");
        }

        byte[] buffer = new byte[1024];
        // Write status line
        if (this.fileExists) {
            System.out.println("Trying to write data");
            try{
                this.out.writeBytes("HTTP/1.0 " + "200 OK " + this.CRLF);
                this.out.flush();
                // Write Header
                this.out.writeBytes("Content-type: " + getMime(this.fileName) + this.CRLF);
                this.out.flush();
                this.out.writeBytes(this.CRLF);
                this.out.flush();

                // Read file data
                byte[] fileData = new byte[1024];

                int i;
                while ((i = this.f.read(fileData)) > 0) {
                    // Write File data
                    try{
                        this.out.write(fileData,0, i);
                    } catch (IOException e) {
                        System.out.println(e);
                    }
                }
                this.out.flush(); // Flush output stream
                System.out.println("Flushed");
                closeSock(); // Closes socket
            } catch (IOException e) {
                e.printStackTrace();
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...