如何解决java.io.IOException:Stream closed和java.lang.IllegalStateException:刷新数据时发生异常?

时间:2017-12-13 07:17:17

标签: java multithreading sockets jsp servlets

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

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

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

2 个答案:

答案 0 :(得分:1)

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

异常实际上似乎是由一个名为Stop_Exposure.doPost的方法正在做的事情引起的。那不是这个代码。

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

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

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

  • 如果您在forward调用返回后尝试写入响应编写器,则会出现错误。规范说:

      

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

答案 1 :(得分:0)

您正在调用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。如果不这样做,将导致内存泄漏和资源锁定。