2007-10-29
如何跟踪 客户端下载是否完成
这是一个技术难题。
需求是:
有一个收费的下载链接,但是是基于用户成功下载才能进行收费。
可是如何判断用户是否成功下载呢?
找了很多的技术文档,没有结果。其中常见的一种方案是:
经过测试,发现这种方法不管客户端是否下载成功都会进行扣费,和
和下面的代码的执行效果是一样的
但是我相信,WEB容器是肯定知道下载是否完成的,而且能够触发下载完成事件,否则,容器怎么知道什么时候停止向客户端发送数据流。
欢迎大家提供思路。
需求是:
有一个收费的下载链接,但是是基于用户成功下载才能进行收费。
可是如何判断用户是否成功下载呢?
找了很多的技术文档,没有结果。其中常见的一种方案是:
String file=request.getParameter("file");//物理文件路径
String filename=file;
if(file.startsWith("/"))
file=session.getServletContext().getRealPath(file);
if(file.indexOf("\\")>-1)
filename=file.substring(filename.lastIndexOf("\\")+1);
String err=null; String txt=null;
System.out.println("filename: "+filename);
byte data[]=null;
try{
InputStream inputStream = new FileInputStream(file); // 以byte流的方式打开文件 d:\1.gif
int i=inputStream.available(); //得到文件大小
data=new byte[i];
inputStream.read(data); //读数据
inputStream.close();
inputStream=null;
}catch(FileNotFoundException e){
err="无法在服务器上获取相关文件!文件不存在.";
}catch(Exception e){
err=e.getMessage();
}
System.out.println(filename);
if(data==null||err!=null){
if(txt!=null)
txt="请求的数据不是合法的二进制格式!";
else{
if(err==null)txt="无法从服务器获取相关文件,文件数据不存在或已经损坏.";
else txt=err;
}
String msg="无法下载文件:"+filename+"\\n"+txt;
return;
}
response.setContentType("application/octet-stream");
response.addHeader("Content-disposition" , "attachment;filename="+filename+"\"");
response.getOutputStream().write(data);
response.getOutputStream().close();
out.clear();
out = pageContext.pushBody();
data=null;
MD5 md=new MD5();
String ip=request.getRemoteHost();
System.out.println("下载成功!");
// 进行下载扣费
经过测试,发现这种方法不管客户端是否下载成功都会进行扣费,和
和下面的代码的执行效果是一样的
response.sendRedirect("dowloadfiel_url");
//进行扣费
但是我相信,WEB容器是肯定知道下载是否完成的,而且能够触发下载完成事件,否则,容器怎么知道什么时候停止向客户端发送数据流。
欢迎大家提供思路。
评论
fins
2007-11-05
rehte 写道
fins:
我觉得你使用socket直接进行编程和使用标准httpserver的结果是一样的。因为httpserver最终最底层也是使用socket实现的。
我觉得你使用socket直接进行编程和使用标准httpserver的结果是一样的。因为httpserver最终最底层也是使用socket实现的。
这点我当然清楚
但是显然楼主不清楚 ,所以我要解释给他听, 客户端断开连接 取消下载后, 服务端是可以知道的.
另外 ,我觉得你说这个和 楼主提的问题 没有什么关系
楼主的问题是
服务器端 如何 判断 客户端成功下载.
这里的问题 是 服务器端 与 客户端 ,是两台机器的事情.
如果非要把人的因素考虑进来 "他在浏览器提示保存时,取消了保存怎么办"
那我问你, 如果他保存了, 可是保存之后,才发现自己下载错了 ,又把文件删除了, 那服务端怎么知道?
楼主的问题是一个技术问题, 而楼上回答的 是一个 收费下载机制的实现方式问题.
我不知道楼主更需要的是哪个答案.
但是,我的观点是:
文件一旦下载到客户端, 那么就应该认为他下载成功了. 而他是否保存,是否删除,以及对他来说是否有用,我们无需关心 也无法正确判断.
毕竟互联网服务不是去超市买东西, 不包退不包换.
你打错电话了, 然后跟移动说, 我打错了, 刚才那电话的花费你别给我扣, 他们会答应吗????
rehte
2007-11-05
fins:
我觉得你使用socket直接进行编程和使用标准httpserver的结果是一样的。因为httpserver最终最底层也是使用socket实现的。退一步讲,使用socket能准确判知客户端浏览器是否下载成功,但是如果用户发现是误点链接造成的下载,他在浏览器提示保存时,取消了保存怎么办?因此还是不准确。只有在索取密码那种办法才能严格断定用户的行为:
1.他的确下载成功了,解压正常,但缺少密码。
2.他的确想使用该软件,如果是误点而实际并不想使用,他就不会索要密码了。要密码就证明了他想用。这儿密码的含义同购买软件serial number一样,具有确保软件真正是到达用户的作用。它间接的起到了证明用户成功获得软件的事实,证明了他主观上的确要想要下载该软件的,而不是误点造成的。
按照你们的做法,如果用户因为误点而被扣费,他们肯定会很生气,甚至会产生诉讼。
我觉得你使用socket直接进行编程和使用标准httpserver的结果是一样的。因为httpserver最终最底层也是使用socket实现的。退一步讲,使用socket能准确判知客户端浏览器是否下载成功,但是如果用户发现是误点链接造成的下载,他在浏览器提示保存时,取消了保存怎么办?因此还是不准确。只有在索取密码那种办法才能严格断定用户的行为:
1.他的确下载成功了,解压正常,但缺少密码。
2.他的确想使用该软件,如果是误点而实际并不想使用,他就不会索要密码了。要密码就证明了他想用。这儿密码的含义同购买软件serial number一样,具有确保软件真正是到达用户的作用。它间接的起到了证明用户成功获得软件的事实,证明了他主观上的确要想要下载该软件的,而不是误点造成的。
按照你们的做法,如果用户因为误点而被扣费,他们肯定会很生气,甚至会产生诉讼。
fins
2007-11-04
fireflyc 写道
fins同学好想忘记了一个问题,HTTP是无状态的。
服务器端发送一段数据(此处是文件)到浏览器,浏览器做相应的处理(此处是保存文件)在这个过程中浏览器只是被动的接受数据,如果在一段时间内没有接受到新的数据就会弹出无法下载的对话框(或者是不断的重试~~~~~)。在这一些行为中浏览器端始终是被动的,无状态的。这个问题从本质上是没有办法解决的。不过有一个非常不错的办法,上面的也有朋友提到了
可以在24小时内对一个账户重复下载一个资源进行一次扣费处理。
比如:
user1下载了一个资源rs1,按照常规的那样提示用户下载,然后扣费处理,如果下载成功也就完成任务了;如果下载失败用户可以重新下载rs1而不会被重复扣费,即使用户下载成功后也是可以重复下载的,(注意重复下载有一个有效时间比如24小时)这并不会造成什么损失(用户已经下载成功了,他重复下载等于说是重他硬盘上copy一份而已)。
服务器端发送一段数据(此处是文件)到浏览器,浏览器做相应的处理(此处是保存文件)在这个过程中浏览器只是被动的接受数据,如果在一段时间内没有接受到新的数据就会弹出无法下载的对话框(或者是不断的重试~~~~~)。在这一些行为中浏览器端始终是被动的,无状态的。这个问题从本质上是没有办法解决的。不过有一个非常不错的办法,上面的也有朋友提到了
可以在24小时内对一个账户重复下载一个资源进行一次扣费处理。
比如:
user1下载了一个资源rs1,按照常规的那样提示用户下载,然后扣费处理,如果下载成功也就完成任务了;如果下载失败用户可以重新下载rs1而不会被重复扣费,即使用户下载成功后也是可以重复下载的,(注意重复下载有一个有效时间比如24小时)这并不会造成什么损失(用户已经下载成功了,他重复下载等于说是重他硬盘上copy一份而已)。
楼主的问题核心是:
服务端 如何 判断 客户端 下载完成.
你说的"HTTP无状态 浏览器端始终是被动的,无状态的...." 和楼主的问题又什么关系吗???
你又说:
"然后扣费处理,如果下载成功也就完成任务了..."
楼主的问题就是, 你如何判断客户端"下载成功"????
fins
2007-11-04
kjava 写道
引用
但是就像我前面说的,有一个误差是无法避免的
就是服务器向客户端发送 最后一个字节 之后, 服务端就认为下载完毕,但是这最后一个字节是否传到了客户端 服务器无法知道,除非你再做个特殊的下载软件.
就是服务器向客户端发送 最后一个字节 之后, 服务端就认为下载完毕,但是这最后一个字节是否传到了客户端 服务器无法知道,除非你再做个特殊的下载软件.
以上是JAVA实现的http server类,很显然,这种方式的误差,不是简单的在服务器发送完最后一个字节的误差,而是客户端在取消下载申请后,服务器断一样会认为客户端已经进行了下载,因为这种方式服务器端不知道客户端已经点击了取消下载按钮。
但是我认为服务器端应该是能够判断出客户端的下载情况的,不需要通过activex,因为那样的话太麻烦。
一个完整的 httpFileserver 应该由自己来启动socket监听的
浏览器 通过socket连接到 httpFileserver , 浏览器断开后(取消下载,非法关闭等), 服务器是可以监听到的
你找的这个例子不能说明问题.
其实楼主举的这个例子 也能说明一些问题
你看那个 HttpOutputStream out
他实际上就是从 Socket.getOutputStream()的来的
如果这时候 客户端的 Socket断开时, out.write (in); 是会抛异常的
很明显的啊.
所以 服务端是可以知道 客户端是否已经下载完成的(除了我所说的那个误差).
请看下面的代码:
byte[] buff = new byte[2048];
while (true){
int read = data.read( buff, 0, buff.length );
if (read <= 0)
break;
out.write( buff, 0, read );
}
out.flush();
out.close();
// 此时 理解为 客户端成功下载完.
下载过程中,如果客户端中断,会抛出异常.你只要拦截处理一下就可以.
而如果顺利的执行完了 while循环,并且close了你就可以认为客户端下载完成了.
实际上,这时候一点误差都不会有, 因为你时在flush和close之后判断的.
如果你服务端不想主动flush 和 close,那么有可能存在2K的误差.
因为你最后一次执行out.write之后,有可能数据没有送到客户端.
只要稍微了解一下 HTTP SOCKET TCP/IP 的基础知识
你就应该能够理解我说的意思了 .
还有一点很重要:
我说的这个方案 是我自己亲自动手实践过的 绝对可行的.
最后再提醒一下楼主:
一个对下载 上传 要求严格的网站 ,必须要有一个很好的 http file server.
httpfile server 一个server级的东西,
而不是一个运行在某j2ee server下的servlet 或web listener.
fireflyc
2007-11-04
fins同学好想忘记了一个问题,HTTP是无状态的。
服务器端发送一段数据(此处是文件)到浏览器,浏览器做相应的处理(此处是保存文件)在这个过程中浏览器只是被动的接受数据,如果在一段时间内没有接受到新的数据就会弹出无法下载的对话框(或者是不断的重试~~~~~)。在这一些行为中浏览器端始终是被动的,无状态的。这个问题从本质上是没有办法解决的。不过有一个非常不错的办法,上面的也有朋友提到了
可以在24小时内对一个账户重复下载一个资源进行一次扣费处理。
比如:
user1下载了一个资源rs1,按照常规的那样提示用户下载,然后扣费处理,如果下载成功也就完成任务了;如果下载失败用户可以重新下载rs1而不会被重复扣费,即使用户下载成功后也是可以重复下载的,(注意重复下载有一个有效时间比如24小时)这并不会造成什么损失(用户已经下载成功了,他重复下载等于说是重他硬盘上copy一份而已)。
服务器端发送一段数据(此处是文件)到浏览器,浏览器做相应的处理(此处是保存文件)在这个过程中浏览器只是被动的接受数据,如果在一段时间内没有接受到新的数据就会弹出无法下载的对话框(或者是不断的重试~~~~~)。在这一些行为中浏览器端始终是被动的,无状态的。这个问题从本质上是没有办法解决的。不过有一个非常不错的办法,上面的也有朋友提到了
可以在24小时内对一个账户重复下载一个资源进行一次扣费处理。
比如:
user1下载了一个资源rs1,按照常规的那样提示用户下载,然后扣费处理,如果下载成功也就完成任务了;如果下载失败用户可以重新下载rs1而不会被重复扣费,即使用户下载成功后也是可以重复下载的,(注意重复下载有一个有效时间比如24小时)这并不会造成什么损失(用户已经下载成功了,他重复下载等于说是重他硬盘上copy一份而已)。
kjava
2007-11-04
/*
* Java Network Programming, Second Edition
* Merlin Hughes, Michael Shoffner, Derek Hamner
* Manning Publications Company; ISBN 188477749X
*
* http://nitric.com/jnp/
*
* Copyright (c) 1997-1999 Merlin Hughes, Michael Shoffner, Derek Hamner;
* all rights reserved; see license.txt for details.
*/
import java.io.*;
public class HttpFile implements HttpProcessor {
protected File file;
public HttpFile (HttpInputStream in) throws IOException {
if (in.getMethod () == HTTP.METHOD_POST)
throw new HttpException (HTTP.STATUS_NOT_ALLOWED,
"<TT>" + in.getMethod () + " " + in.getPath () + "</TT>");
file = new File (HTTP.HTML_ROOT, HTTP.translateFilename (in.getPath ()));
if (in.getPath ().endsWith ("/"))
file = new File (file, HTTP.DEFAULT_INDEX);
if (!file.exists ())
throw new HttpException (HTTP.STATUS_NOT_FOUND,
"File <TT>" + in.getPath () + "</TT> not found.");
if (file.isDirectory ())
throw new RedirectException (HTTP.STATUS_MOVED_PERMANENTLY,
in.getPath () + "/");
if (!file.isFile () || !file.canRead ())
throw new HttpException (HTTP.STATUS_FORBIDDEN, in.getPath ());
}
public void processRequest (HttpOutputStream out) throws IOException {
out.setHeader ("Content-type", HTTP.guessMimeType (file.getName ()));
out.setHeader ("Content-length", String.valueOf (file.length ()));
if (out.sendHeaders ()) {
FileInputStream in = new FileInputStream (file);
out.write (in);
in.close ();
}
}
}
引用
但是就像我前面说的,有一个误差是无法避免的
就是服务器向客户端发送 最后一个字节 之后, 服务端就认为下载完毕,但是这最后一个字节是否传到了客户端 服务器无法知道,除非你再做个特殊的下载软件.
就是服务器向客户端发送 最后一个字节 之后, 服务端就认为下载完毕,但是这最后一个字节是否传到了客户端 服务器无法知道,除非你再做个特殊的下载软件.
以上是JAVA实现的http server类,很显然,这种方式的误差,不是简单的在服务器发送完最后一个字节的误差,而是客户端在取消下载申请后,服务器断一样会认为客户端已经进行了下载,因为这种方式服务器端不知道客户端已经点击了取消下载按钮。
但是我认为服务器端应该是能够判断出客户端的下载情况的,不需要通过activex,因为那样的话太麻烦。
fins
2007-11-04
这个问题 最好的解决方案就是自己写个简单的httpFile Server这个不难
网上有很多实现,简单的只要一个类就搞定
这样你就可以处理很多事情了
但是就像我前面说的,有一个误差是无法避免的
就是服务器向客户端发送 最后一个字节 之后, 服务端就认为下载完毕,但是这最后一个字节是否传到了客户端 服务器无法知道,除非你再做个特殊的下载软件.
网上有很多实现,简单的只要一个类就搞定
这样你就可以处理很多事情了
但是就像我前面说的,有一个误差是无法避免的
就是服务器向客户端发送 最后一个字节 之后, 服务端就认为下载完毕,但是这最后一个字节是否传到了客户端 服务器无法知道,除非你再做个特殊的下载软件.
renavatior
2007-11-04
这个可以用AJAX实现的吧,当下载完成它会触发一个事件这个时候提醒服务器端扣费
rehte
2007-11-04
我认为在不使用ActiveX等客户端下载软件的情况下,使用浏览器链接下载,可能只有上面那位老兄提的下载再索取密码扣费的方式是最准确的,甚至也只有那种办法才能确保用户真正的得到你的软件。
kjava
2007-11-03
引用
关键是“客户端下载是否完成”这个怎么理解?是不是当用户把文件完全保存到本地硬盘之后才算下载完成?
不错,客户端下载完成的含义就是用户把文件保存到本地硬盘。
之所以进行这样的定义,是为了更准确地判断出,该点击用户确实是想下载该文件的用户,而不是被误导或是其他不正常原因而导致点击了下载链接。因为后面紧跟着扣费操作!
如果用户仅仅是点击了下载连接,而取消了下载确认对话框,那么显然,这个用户对该文件不感兴趣,扣费操作是不应该执行的。
而且,我想知道的是,如果不能准确判断用户是否下载了文件,为什么要用一大堆的代码去 读文件,发文件,而不是用一条 response.sendForward(url),效果不是一样的吗?
someone
2007-11-02
fins 写道
客户端 发送请求
服务端得到请求
服务端去读文件
服务端将读到的文件发送给客户端
服务端读取并发送完全部文件后,可以理解为客户端已经完成下载.
如果这期间客户端 中止下载, 那么服务端可以得到客户端的链接断开的信息
当然 这个思路是有误差的, 误差发生在最后时刻.
服务端"读取并发送完全部文件",但是客户端还没有接收到最后发送的那一部分内容时,会出现一点点误差,但是应该可以忽略不计的.
服务端得到请求
服务端去读文件
服务端将读到的文件发送给客户端
服务端读取并发送完全部文件后,可以理解为客户端已经完成下载.
如果这期间客户端 中止下载, 那么服务端可以得到客户端的链接断开的信息
当然 这个思路是有误差的, 误差发生在最后时刻.
服务端"读取并发送完全部文件",但是客户端还没有接收到最后发送的那一部分内容时,会出现一点点误差,但是应该可以忽略不计的.
关键是“客户端下载是否完成”这个怎么理解?是不是当用户把文件完全保存到本地硬盘之后才算下载完成?
对于Web系统Download文件,是不可能在服务器端完全准确地判断文件是否Download成功了。浏览器都有buffer,对比较小的文件,当OutputStream().write已经结束,也就是数据已经完全发送到客户端,这个时候HttpConnect会关闭,一次Http会话结束,而这时客户端会弹出保存文件的对话框,当客户选择Cancel的时候,服务器端已经完全不知道了。
所以“跟踪 客户端下载是否完成”是无法实现的,除非你自己做ActiveX来下载。
kjava
2007-11-02
to fins
以上的代码思路是不正确的,response.getOutputStream().write();写的数据其实还在服务器端,请求下载文件的触发请求 与 相应文件输出的下载流的操作 应该不是同一个线程,所以,以上的思路在下载过程中就会进行扣费。
引用
客户端 发送请求
服务端得到请求
服务端去读文件
服务端将读到的文件发送给客户端
服务端读取并发送完全部文件后,可以理解为客户端已经完成下载.
如果这期间客户端 中止下载, 那么服务端可以得到客户端的链接断开的信息
当然 这个思路是有误差的, 误差发生在最后时刻.
服务端"读取并发送完全部文件",但是客户端还没有接收到最后发送的那一部分内容时,会出现一点点误差,但是应该可以忽略不计的.
服务端得到请求
服务端去读文件
服务端将读到的文件发送给客户端
服务端读取并发送完全部文件后,可以理解为客户端已经完成下载.
如果这期间客户端 中止下载, 那么服务端可以得到客户端的链接断开的信息
当然 这个思路是有误差的, 误差发生在最后时刻.
服务端"读取并发送完全部文件",但是客户端还没有接收到最后发送的那一部分内容时,会出现一点点误差,但是应该可以忽略不计的.
response.setContentType("application/octet-stream");
response.addHeader("Content-disposition" , "attachment;filename="+filename+"\"");
while(发送文件大小完成)
{
response.getOutputStream().write(data1);
response.getOutputStream().write(data2);
.......
}
扣费操作.....
response.getOutputStream().close();
以上的代码思路是不正确的,response.getOutputStream().write();写的数据其实还在服务器端,请求下载文件的触发请求 与 相应文件输出的下载流的操作 应该不是同一个线程,所以,以上的思路在下载过程中就会进行扣费。
myy
2007-11-01
lszone 写道
myy 写道
服务端判断不太好做,也很不可靠。
建议这样:
将收费的东西打包压缩并加密码(最好能动态压缩),让别人随便下,但是没法直接用,然后用户必须点击页面的“扣费”按钮,进行扣费,才给出密码(也可以通过邮件发到用户邮箱中)
建议这样:
将收费的东西打包压缩并加密码(最好能动态压缩),让别人随便下,但是没法直接用,然后用户必须点击页面的“扣费”按钮,进行扣费,才给出密码(也可以通过邮件发到用户邮箱中)
典型的不考虑产品的做法,对于一些方案总想绕道而行,你这种做法无疑是提高了操作的复杂性
很多共享软件就是这样做的,人家不是做产品么?
再说了,为什么要有麻烦的https,不就是因为http不安全绕道而行么?
“提高了操作的复杂性”是在有限条件下,需求要求过高 所必须付出的代价。
lszone
2007-11-01
myy 写道
服务端判断不太好做,也很不可靠。
建议这样:
将收费的东西打包压缩并加密码(最好能动态压缩),让别人随便下,但是没法直接用,然后用户必须点击页面的“扣费”按钮,进行扣费,才给出密码(也可以通过邮件发到用户邮箱中)
建议这样:
将收费的东西打包压缩并加密码(最好能动态压缩),让别人随便下,但是没法直接用,然后用户必须点击页面的“扣费”按钮,进行扣费,才给出密码(也可以通过邮件发到用户邮箱中)
典型的不考虑产品的做法,对于一些方案总想绕道而行,你这种做法无疑是提高了操作的复杂性
bearlz
2007-11-01
我以前在一家新闻图片销售公司做的时候,记录客户第一次下载的时间,生成订单,然后在一段时间内是免费下载的。
控制客户端感觉比较难
控制客户端感觉比较难
timerri
2007-11-01
try{
response.getOutputStream().write(data);
response.getOutputStream().close();
}catch(e ...){
//失败
}
其实,这样就足够了,如果还是出问题,那就肯定是客户端的问题。
你们其实设计思路有问题,应该不是如何保证全部正确发送,这基本是做不到的,因为你不能保证客户端的正确与否,而是要保证客户在出现问题后还能有补救的办法,比如再让他能免费下一次。
response.getOutputStream().write(data);
response.getOutputStream().close();
}catch(e ...){
//失败
}
其实,这样就足够了,如果还是出问题,那就肯定是客户端的问题。
你们其实设计思路有问题,应该不是如何保证全部正确发送,这基本是做不到的,因为你不能保证客户端的正确与否,而是要保证客户在出现问题后还能有补救的办法,比如再让他能免费下一次。
myy
2007-11-01
[quote="kjava"]to myy
[quote]try{
InputStream inputStream = new FileInputStream(file); // 以byte流的方式打开文件 d:\1.gif
int i=inputStream.available(); //得到文件大小
data=new byte[i];
inputStream.read(data); //读数据
//
// 带密码压缩数据
//
不知道这段怎么理解?
to
inputStream.close();
inputStream=null;
}catch(FileNotFoundException e){
err="无法在服务器上获取相关文件!文件不存在.";
}catch(Exception e){
err=e.getMessage();
} [/quote]
这不好理解么?
数据是服务端输出的,在输出前,压缩并加密了一下而已,比如简单一点可以这样:
1.用户 "user01" 请求文件"thedoc.doc"(如: http://.../getfile.jsp?file=thedoc.doc )
2.getfile.jsp先找到真正的thedoc.doc,并随机生成一个密码"asdfgh"(规则自定义)
3.getfile.jsp用命令行带参数(包括密码"asdfgh")调用rar.exe, 生成临时文件 user01_20071101100505_thedoc.doc.rar(规则自定义)
4.将文件名"user01_20071101100505_thedoc.doc.rar" 和 密码 "asdfgh"存入数据库
5.将文件 user01_20071101100505_thedoc.doc.rar 输出到用户
...
6.用户下载完成,用 winrar 打开(利用 winrar 验证文件是否完整),发现要密码才能解压,于是必须点“扣费”按钮(同时输入文件名"user01_20071101100505_thedoc.doc.rar"), 后台从数据库根据文件名,取出密码 "asdfgh"显示给用户。
[quote]try{
InputStream inputStream = new FileInputStream(file); // 以byte流的方式打开文件 d:\1.gif
int i=inputStream.available(); //得到文件大小
data=new byte[i];
inputStream.read(data); //读数据
//
// 带密码压缩数据
//
不知道这段怎么理解?
to
inputStream.close();
inputStream=null;
}catch(FileNotFoundException e){
err="无法在服务器上获取相关文件!文件不存在.";
}catch(Exception e){
err=e.getMessage();
} [/quote]
这不好理解么?
数据是服务端输出的,在输出前,压缩并加密了一下而已,比如简单一点可以这样:
1.用户 "user01" 请求文件"thedoc.doc"(如: http://.../getfile.jsp?file=thedoc.doc )
2.getfile.jsp先找到真正的thedoc.doc,并随机生成一个密码"asdfgh"(规则自定义)
3.getfile.jsp用命令行带参数(包括密码"asdfgh")调用rar.exe, 生成临时文件 user01_20071101100505_thedoc.doc.rar(规则自定义)
4.将文件名"user01_20071101100505_thedoc.doc.rar" 和 密码 "asdfgh"存入数据库
5.将文件 user01_20071101100505_thedoc.doc.rar 输出到用户
...
6.用户下载完成,用 winrar 打开(利用 winrar 验证文件是否完整),发现要密码才能解压,于是必须点“扣费”按钮(同时输入文件名"user01_20071101100505_thedoc.doc.rar"), 后台从数据库根据文件名,取出密码 "asdfgh"显示给用户。
smyl9989
2007-10-31
我怀疑你这个地方有没有try一下
response.getOutputStream().write(data);
response.getOutputStream().close();
还有什么原因会导致客户端还没下完就出故障?突然停电?这是客户端的问题,这个难道还得你们负责啊
response.getOutputStream().write(data);
response.getOutputStream().close();
还有什么原因会导致客户端还没下完就出故障?突然停电?这是客户端的问题,这个难道还得你们负责啊
ddandyy
2007-10-31
文件大约有多大........ 可以用下载软件下载么......
fins
2007-10-31
客户端 发送请求
服务端得到请求
服务端去读文件
服务端将读到的文件发送给客户端
服务端读取并发送完全部文件后,可以理解为客户端已经完成下载.
如果这期间客户端 中止下载, 那么服务端可以得到客户端的链接断开的信息
当然 这个思路是有误差的, 误差发生在最后时刻.
服务端"读取并发送完全部文件",但是客户端还没有接收到最后发送的那一部分内容时,会出现一点点误差,但是应该可以忽略不计的.
服务端得到请求
服务端去读文件
服务端将读到的文件发送给客户端
服务端读取并发送完全部文件后,可以理解为客户端已经完成下载.
如果这期间客户端 中止下载, 那么服务端可以得到客户端的链接断开的信息
当然 这个思路是有误差的, 误差发生在最后时刻.
服务端"读取并发送完全部文件",但是客户端还没有接收到最后发送的那一部分内容时,会出现一点点误差,但是应该可以忽略不计的.
- 浏览: 4850 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
我的相册
DSC02765
共 1 张
共 1 张
最近加入圈子
最新评论
-
看看大家的IT学习力在什么 ...
那我不是完蛋了,按照上面的规则推断就是...溢出... 我不仅直接读代码,还常 ...
-- by acdc -
看看大家的IT学习力在什么 ...
幼稚班。。。
-- by longbiezai -
看看大家的IT学习力在什么 ...
Trustno1 写道其实,我不觉得直接读论文或者源代码会比读书来的快.做这两件 ...
-- by charon -
看看大家的IT学习力在什么 ...
啥也没看到,就看到csdn对业界的影响力。
-- by maxiaoxia -
看看大家的IT学习力在什么 ...
小学。沿着老庄的道路前进。
-- by smalljeff






评论排行榜