Servlet IO限速的一种粗略实现
来源:互联网 发布:unity3d 机械仿真 编辑:程序博客网 时间:2024/04/29 13:56
本实现参考了 Daniel Matuschek - A FilterInputStream with a limited bandwith
分别为设置下载限制速度为1MB/s 128KB/s 256KB/s,使用wget测试下载速度
测试结果如图:
代码如下:
package com.bimwinner.commons.web.filter;import java.io.IOException;import java.util.ArrayList;import java.util.List;import java.util.StringTokenizer;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ReadListener;import javax.servlet.ServletException;import javax.servlet.ServletInputStream;import javax.servlet.ServletOutputStream;import javax.servlet.ServletRequest;import javax.servlet.ServletRequestWrapper;import javax.servlet.ServletResponse;import javax.servlet.ServletResponseWrapper;import javax.servlet.WriteListener;import javax.servlet.annotation.WebFilter;import javax.servlet.annotation.WebInitParam;/** * Simple QoS limit filter * <b>Note: </b> * input limit works only when <code>request.getInputStream()</code> was invoked; * (e.g. form-data upload don't, binary upload do)<br/> * output limit works only when <code>response.getOutputStream()</code> was invoked; * (e.g. jsp html don't, servlet download do) * @author Fuwei Chin */@WebFilter(filterName="QoS",initParams={ @WebInitParam(name="outputLimit",value="1*1024*1024")})public class QoSFilter implements Filter { private int inputLimit=-1; private int outputLimit=-1; @Override public void init(FilterConfig filterConfig) throws ServletException { Double inputLimit=eval(filterConfig.getInitParameter("inputLimit")); if(inputLimit!=null){ this.inputLimit=inputLimit.intValue(); } Double outputLimit=eval(filterConfig.getInitParameter("outputLimit")); if(outputLimit!=null){ this.outputLimit=outputLimit.intValue(); } } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { chain.doFilter(inputLimit<=0?req:new QoSServletRequestWrapper(req,inputLimit), outputLimit<=0?res:new QoSServletResponseWrapper(res,outputLimit)); } @Override public void destroy() { } private static Double eval(String expr){ if(expr==null){ return null; } List<Double> values=new ArrayList<>(); StringTokenizer st=new StringTokenizer(expr, "*"); while(st.hasMoreTokens()){ values.add(Double.parseDouble(st.nextToken())); } if(values.size()>0){ double result=1d; for(Double i:values){ result*=i; } return result; } return null; }}class QoSServletRequestWrapper extends ServletRequestWrapper { private int limit; private ServletInputStream in; public QoSServletRequestWrapper(ServletRequest request,int limit) { super(request); this.limit=limit; } @Override public ServletInputStream getInputStream() throws IOException { if(in==null){ in=new QosServletInputStream(super.getInputStream(), this.limit); } return in; }}class QoSServletResponseWrapper extends ServletResponseWrapper { private int limit; private ServletOutputStream out; public QoSServletResponseWrapper(ServletResponse response,int limit) { super(response); this.limit=limit; } @Override public ServletOutputStream getOutputStream() throws IOException { if(out==null){ out=new QoSServletOutputStream(super.getOutputStream(), this.limit); } return out; }}class QosServletInputStream extends ServletInputStream { private ServletInputStream in; private int limit; private int read; private long startTime; public QosServletInputStream(ServletInputStream in,int limit) { this.in=in; this.limit=limit; } @Override public int read() throws IOException { int r=in.read(); if(r!=-1&&(this.read+=1)>limit){ checkSpeed(); } return r; } @Override public int read(byte[] b) throws IOException { return this.read(b,0,b.length); } @Override public int read(byte[] b, int off, int len) throws IOException { int r=in.read(b, off, len); if(r!=-1&&(this.read+=r)>limit){ checkSpeed(); } return r; } @Override public long skip(long n) throws IOException { return in.skip(n); } @Override public int available() throws IOException { return in.available(); } @Override public synchronized void mark(int readlimit) { in.mark(readlimit); } @Override public synchronized void reset() throws IOException { in.reset(); } @Override public boolean markSupported() { return in.markSupported(); } @Override public void close() throws IOException { in.close(); } @Override public boolean isFinished() { return in.isFinished(); } @Override public boolean isReady() { return in.isReady(); } @Override public void setReadListener(ReadListener listener) { in.setReadListener(listener); } private void checkSpeed(){ long elapsedTime=System.currentTimeMillis()-startTime; long sleepTime=1000-elapsedTime; if(sleepTime>0){ try { System.out.println("sleep "+sleepTime); Thread.sleep(sleepTime); } catch (InterruptedException e) { } } this.read=0; this.startTime=System.currentTimeMillis(); }}class QoSServletOutputStream extends ServletOutputStream { private ServletOutputStream out; private int limit; private int written; private long startTime; public QoSServletOutputStream(ServletOutputStream out,int limit) { this.out=out; this.limit=limit; } @Override public void write(int b) throws IOException { out.write(b); if((this.written+=1)>limit){ checkSpeed(); } } @Override public void write(byte[] b) throws IOException { this.write(b, 0, b.length); } @Override public void write(byte[] b, int off, int len) throws IOException { out.write(b, off, len); if((this.written+=len)>limit){ checkSpeed(); } } @Override public void flush() throws IOException { out.flush(); } @Override public void close() throws IOException { out.close(); } @Override public boolean isReady() { return out.isReady(); } @Override public void setWriteListener(WriteListener listener) { out.setWriteListener(listener); } private void checkSpeed(){ long elapsedTime=System.currentTimeMillis()-startTime; long sleepTime=1000-elapsedTime; if(sleepTime>0){ try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } } this.written=0; this.startTime=System.currentTimeMillis(); }}
阅读全文
0 0
- Servlet IO限速的一种粗略实现
- 简单限速器的实现
- 一种接口限速方案
- 一种接口限速方案
- 一种粗略的普通摄像头深度信息提取方法
- 一种粗略的普通摄像头深度信息提取方法
- 链表实现的粗略的通讯录
- FTP限速的实现算法(01)
- 基于连接的每IP限速实现
- linux下ipv6的Qos限速实现
- 粗略记述实习项目的大概实现
- 简单工厂模式实现粗略的四则运算
- MVC servlet 单个功能的后台过程(粗略)
- Servlet学习笔记—实现Servlet接口(创建Servlet的第一种方法)
- 利用servlet规范,一种实现动态路径的方法
- Apache实现限速(针对每个客户端限速)
- zab粗略实现
- 实现pi粗略计算
- 实验三:递归下降分析法
- codeforces 745C 联通
- java 集合泛型案例说明
- 穷举法
- bzoj1304 [CQOI2009]叶子的染色 dfs+树形dp
- Servlet IO限速的一种粗略实现
- MySql视图、存储过程和触发器
- 【Python】python 学习笔记 --画图(networkx)
- (翻译)模块标签( Module Tabs)
- 统计量MAD
- Oracle job为什么不能自动执行
- 小程序-登录态维护
- Java小游戏之推箱子游戏
- java中static的用法