为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

胡子哥哥 2024-01-05 16:27:09
我正在为一个学校项目开发一个多线程网络服务器。我应该能够在浏览器上进入本地主机并请求 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);谢谢,如有任何帮助,我们将不胜感激。
查看完整描述

1 回答

?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

问题在于响应标头的格式不正确,导致连接过早结束。必须在标头之后发送另一个空行(“\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();

            }


查看完整回答
反对 回复 2024-01-05
  • 1 回答
  • 0 关注
  • 40 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信