如果用Servlet做文件下载的话,当用户中途取消了下载那么Servlet是会继续向用户传送没有传送完的文件还是Servlet会自动关闭当前线程?

文章探讨了使用Servlet进行文件下载时,用户中途取消下载后服务器端业务逻辑处理的问题。测试发现,即使用户关闭浏览器,Servlet线程仍然运行,导致文件下载未停止。解释了这一现象背后的TCP连接状态变化,并讨论了如何通过连接与关闭链接来可能攻击服务器的方法及设置策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 的等待时间后操作系统就回收占用的端口。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值