-
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
// TODO Auto-generated method stub
-
int LENGTH=10240;
-
InputStream is=request.getInputStream();
-
String fn=UUID.randomUUID().toString();
-
File a=new File(HlsConfigure.getPath()+fn);
-
byte []content=new byte[LENGTH];
-
int length;
-
OutputStream os =new FileOutputStream(a);
-
PrintWriter out = response.getWriter();
-
out.write("
bytes | speed KB/s |
");
-
long total=0;
-
long vb=System.currentTimeMillis();
-
again:
-
while(true){
-
int total_length=0;
-
long begin=System.currentTimeMillis();
-
while((length=is.read(content))!=-1){
-
os.write(content, 0, length);
-
System.out.println("get "+length);
-
total_length+=length;
-
if(total_length>=200*1024){
-
break;
-
}
-
}
-
System.out.println("will write speed");
-
long time=System.currentTimeMillis()-begin;
-
out.write("
");
-
out.write(Integer.toString(total_length));
-
out.write("
| ");
-
out.write(Double.toString(total_length/(1.0240)/(time)));
-
out.write("
|
");
-
total+=total_length;
-
out.flush();
-
if(length==-1)
-
break;
-
}
-
os.close();
-
long time=System.currentTimeMillis()-vb;
-
out.write("
");
-
out.write(Long.toString(total));
-
out.write("
| ");
-
String speed=Double.toString(total/(1.0240)/(time));
-
out.write(speed);
-
out.write("
|
");
-
out.flush();
-
out.write("
");
-
System.out.println("from "+request.getRemoteAddr()+ " speed is "+speed);
-
// a.delete();
-
}
代码很简单:
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) |