Chinaunix首页 | 论坛 | 博客
  • 博客访问: 285876
  • 博文数量: 124
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 21
  • 用 户 组: 普通用户
  • 注册时间: 2016-08-20 14:44
文章分类

全部博文(124)

文章存档

2020年(1)

2018年(2)

2016年(2)

2015年(6)

2014年(10)

2013年(23)

2012年(7)

2011年(18)

2010年(15)

2009年(8)

2007年(8)

2006年(23)

2005年(1)

我的朋友

分类: Java

2014-12-20 23:36:40


点击(此处)折叠或打开

  1. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2.         // TODO Auto-generated method stub
  3.         int LENGTH=10240;
  4.         InputStream is=request.getInputStream();
  5.         String fn=UUID.randomUUID().toString();
  6.         File a=new File(HlsConfigure.getPath()+fn);
  7.         byte []content=new byte[LENGTH];
  8.         int length;
  9.         OutputStream os =new FileOutputStream(a);
  10.          PrintWriter out = response.getWriter();
  11.          out.write("");
  12.          long total=0;
  13.          long vb=System.currentTimeMillis();
  14. again:
  15.         while(true){
  16.             int total_length=0;
  17.             long begin=System.currentTimeMillis();            
  18.             while((length=is.read(content))!=-1){
  19.                 os.write(content, 0, length);
  20.                 System.out.println("get "+length);
  21.                 total_length+=length;
  22.                 if(total_length>=200*1024){
  23.                     break;
  24.                 }                
  25.             }
  26.             System.out.println("will write speed");
  27.             long time=System.currentTimeMillis()-begin;
  28.             out.write("
  29. ");
  30.             total+=total_length;
  31.             out.flush();
  32.             if(length==-1)
  33.                 break;
  34.         }
  35.          os.close();    
  36.          long time=System.currentTimeMillis()-vb;
  37.             out.write("
  38. ");
  39.             out.flush();
  40.          out.write("
  41. bytesspeed KB/s
    ");
  42.             out.write(Integer.toString(total_length));
  43.             out.write("
  44. ");
  45.             out.write(Double.toString(total_length/(1.0240)/(time)));                
  46.             out.write("
  47. ");
  48.             out.write(Long.toString(total));
  49.             out.write("
  50. ");
  51.             String speed=Double.toString(total/(1.0240)/(time));
  52.             out.write(speed);                
  53.             out.write("
  54. "
    );
  55.          System.out.println("from "+request.getRemoteAddr()+ " speed is "+speed);
  56.         // a.delete();
  57.     }

代码很简单:
1. 打开inputstream,读流,并写到文件中去;
2. 每200k反馈上传速度;
3. 客户段用最简单的input type='file‘上传文件;

但是当客户上传一个很大的文件时,不能传完就hang了。
最终分析到原因为:
1. 浏览器在没有完成发送请求时,是不会读取服务器输出的。所以这个实时显示上传速度的想法不对; 
2. 从代码执行逻辑看,客户段上传,服务段收数据,不会导致服务器缓冲区满;
3. 但是由于1的原因,服务器返回给客户段的数据不会被从缓冲区读取。所以客户段的缓冲去会满;
4. 从而导致28行的write写不出去;
5. 由于此时服务器堵在了write处,所以服务器也不会再读取数据了。
6. 服务器的缓冲区满了,所以客户的上传就hang住了。

注意:
ACK报文是tcp协议栈实现的。所以无论程序是否读取缓冲区的数据,ACK是不会受到影响的。如果不都数据window值会变小; 这个标记可以用来指示程序是不是没有读数据;

阅读(2873) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~