【问题标题】:How to solve java.io.IOException: Stream closed and java.lang.IllegalStateException: Exception occurred when flushing data?java.io.IOException: Stream closed and java.lang.IllegalStateException: 刷新数据时发生异常如何解决?
【发布时间】:2017-12-13 07:17:17
【问题描述】:

我想向服务器发送一些命令,服务器将发送相同的确认。单击 jsp 页面上的按钮时将触发命令。问题是服务器正在获取命令但客户端无法接受 ack由于以上两个例外。

这是我的客户端发送命令和接收确认

public void Stop_Exposure(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //response.setContentType( "text/html" ) ;
    PrintWriter out = response.getWriter();

    //Socket socket = null;
    Socket socket = new Socket("192.168.13.189", 1026);
    BufferedWriter bw = null;
    BufferedReader br = null;
    try {
        //Send the message to the server
        OutputStream os = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(os);
        bw = new BufferedWriter(osw);

        String command = "Stop_Exposure";
        //  String sendMessage = command + "\n";
        bw.write(command);
        //  bw.flush();
        System.out.println("Message sent to the server : "+command);
        request.getRequestDispatcher("/Control_Panel.jsp").forward(request, response);

        //Get the return message from the server
        InputStream is = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        br = new BufferedReader(isr);
        String message = br.readLine();
        System.out.println("Message received from the server : " +message);    

    } catch (Exception exception) {
        exception.printStackTrace();
    } finally {
        //..    br.close();
        //..    bw.flush();
        //..    bw.close();
        //Closing the socket
        try {
            socket.close();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

这是我的服务器代码

class Socket2 implements Runnable {
    public void run() {
        try {
            ServerSocket ss1 = new ServerSocket(1026);// ("192.168.13.189",1025);
            while (true) {
                Socket s1 = ss1.accept();
                InputStream is1 = s1.getInputStream();
                InputStreamReader isr1 = new InputStreamReader(is1);
                String ack = null;
                BufferedReader br = new BufferedReader(isr1);
                String command = br.readLine();
                System.out.println("Message received..." + command);

                // Sending the response back to the client.
                OutputStream os = s1.getOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(os);
                BufferedWriter bw = new BufferedWriter(osw);
                if (command.equals("Stop_Exposure")) {
                    ack = "Ok";
                    bw.write(ack);
                } else {
                    ack = "Error";
                    bw.write(ack);
                }
                System.out.println("Message sent to the client is " + ack);
                // .. bw.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Dec 13, 2017 1:34:18 PM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet [jsp] threw exception
java.io.IOException: Stream closed
	at org.apache.jasper.runtime.JspWriterImpl.ensureOpen(JspWriterImpl.java:187)
	at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:105)
	at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:171)
	at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:120)
	at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:75)
	at org.apache.jsp.Control_005fPanel_jsp._jspService(Control_005fPanel_jsp.java:6294)
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:443)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:710)
	at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:580)
	at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:516)
	at Stop_Exposure.doPost(Stop_Exposure.java:61)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:498)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:796)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1366)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

org.apache.jasper.JasperException: java.lang.IllegalStateException: Exception occurred when flushing data
	at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:565)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:710)
	at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:580)
	at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:516)
	at Stop_Exposure.doPost(Stop_Exposure.java:61)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:475)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:498)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:796)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1366)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Exception occurred when flushing data
	at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:182)
	at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:120)
	at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:75)
	at org.apache.jsp.Control_005fPanel_jsp._jspService(Control_005fPanel_jsp.java:6294)
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:443)
	... 33 more
Caused by: java.io.IOException: Stream closed
	at org.apache.jasper.runtime.JspWriterImpl.ensureOpen(JspWriterImpl.java:187)
	at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:105)
	at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:171)
	... 39 more

【问题讨论】:

标签: java multithreading sockets jsp servlets


【解决方案1】:

堆栈跟踪中显示的异常在此代码中根本没有发生。如您所见,它发生在 Jasper 代码中,同时尝试释放 PageContext 并刷新 response 输出流。不涉及 Socket 流和套接字服务器代码。

该异常实际上似乎是由名为Stop_Exposure.doPost 的方法正在执行的操作引起的。这不是这个代码。

另一件事是您的Stop_Exposure 方法没有多大意义:

  • 如果目标是异步处理从套接字服务获得的内容,那么这是一种不好的方法 (IMO)。在 JSP 完成对响应的格式化之前,对forward 的调用不会返回。那么这个代码会等到socket服务器的响应到达后才释放请求线程。

  • 您打开了响应编写器,但实际上并未使用它。相反,您正在将内容写入网络容器的标准输出。这将转到某处的日志文件……而不是发送 HTTP 请求的浏览器。

  • 如果您在forward 调用返回后确实尝试写入响应编写器,则会收到错误消息。规范说:

    “在RequestDispatcher接口的forward方法无异常返回之前,必须发送并提交响应内容,并由servlet容器关闭。”

【讨论】:

  • 谢谢。我能够删除错误,但现在的问题是我的服务器不接受命令并且即使进程已经启动也无法发送确认。
  • 写一个新问题。确保包含对问题的清晰描述以及相关代码。换句话说,从你在问这个问题时所犯的错误中吸取教训! (提示:如果您第一次正确地提出问题,那么您不太可能被否决.....)
【解决方案2】:

你正在调用 writer.close();在你写完之后。一旦一个流被关闭,它就不能被再次写入。通常,我实现这一点的方法是将关闭从写入方法移出。

public void writeToFile(){
    String file_text= pedStatusText + "     " + gatesStatus + "     " +  DrawBridgeStatusText;
      try {
         writer.write(file_text);
          writer.flush();
      } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
  }

并添加一个方法 cleanUp 来关闭流。

public void cleanUp() {
     writer.close();
}

这意味着您有责任确保在完成对文件的写入后调用 cleanUp。不这样做会导致内存泄漏和资源锁定。

【讨论】:

    猜你喜欢
    • 2012-09-01
    • 2014-05-18
    • 1970-01-01
    • 2018-11-12
    • 2014-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    相关资源
    最近更新 更多