http://bbs.youkuaiyun.com/topics/340224129
如果用Servlet做文件下载的话,当用户中途取消了下载那么Servlet是会继续向用户传送没有传送完的文件还是Servlet会自动关闭当前线程?
下面是做的输出测试,这个测试模拟的是服务器端业务逻辑处理速度过慢时用户关闭浏览器Servlet的业务逻辑是否会自动关闭。经测试发现Servlet并没有关闭,而是一直运行着Servlet线程。
正常来说服务器应该会知道用户的链接已经断开了的,由于客户端并没有对服务器发送的包产生回馈,这表示网络连接已经断开,这时服务器应该自动关闭该网络连接对应的线程了。但是在Tomcat6.02下并没有关闭该线程。
如果这是大部分服务器的通病的话那么是否可以通过连接与关闭下载文件链接或者其他页面内容较多的链接来攻击该服务器呢?
如果是可以设置的那么应该如何设置呢?测试代码在下面,关闭浏览器后800S时间Servlet的线程还在运行。
package com.wan2go.test.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CloseTest extends HttpServlet { /** * Constructor of the object. */ public CloseTest() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here }
/** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out .println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" This is "); for(int i = 0; i < 10000; i++){ out.println("a"+i+"<br>"); System.out.println("I'm out printing. Current num is "+i); out.flush(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } out.print(this.getClass()); out.println(", using the GET method"); out.println(" </BODY>"); out.println("</HTML>"); System.out.println("I'm closed!"); out.flush(); out.close(); }
/** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out
.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.println("<HTML>"); out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" This is "); out.print(this.getClass()); out.println(", using the POST method"); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } }
回答:
===========================================
会继续执行,TCP 连接还处于等待关闭关态,服务端会执行完成,只是用户收不到了。
如果 HTTP 请求服务端还未完成,客户端就强制取消,这时 TCP 会变为 FIN_WAIT_1 和 FIN_WAIT_2 状态,服务端会进入 CLOSE_WAIT 状态,只有等到服务端全部处理完成后,客户端的 TCP 才会变成 TIME_WAIT 状态,经过 2MSL 的等待时间后操作系统就回收占用的端口。