如何修复 Broken Pipe Socket 异常 (Java)?连接在哪里被关闭?

我正在为一个学校项目开发一个多线程网络服务器。我应该能够在浏览器上进入本地主机并请求 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;

        }


对于浏览器中的一个 .htm 文件,该文件和 html 看起来都很好。但看起来它在 html 文件中对 .jpeg 文件发出了第二个请求,并且浏览器在每次写入数据时都会卡住加载 java.net.SocketException: Broken pipeline (Write failed)


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

谢谢,如有任何帮助,我们将不胜感激。


胡子哥哥
浏览 125回答 1
1回答

梵蒂冈之花

问题在于响应标头的格式不正确,导致连接过早结束。必须在标头之后发送另一个空行(“\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();            }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java