在线网络速度测试JAVA程序(一):思路和控制台主程序【转】

简介: 来源:http://hancool.blog.51cto.com/1836252/1352228 事情的缘由 因上级公司的信息化主管部门经常被投诉说是各种业务应用系统反映系统使用慢的问题,而都把问题归结于网速不给力。

来源:http://hancool.blog.51cto.com/1836252/1352228

事情的缘由

因上级公司的信息化主管部门经常被投诉说是各种业务应用系统反映系统使用慢的问题,而都把问题归结于网速不给力。而业务系统一部份是总公司一级部署的,其它很多都是各个业务部门各自为政建设的,不知道从哪里找来的各种小公司,搞的五法八门的技术路线,没得统一标准、技术平台,所以水平就参差不齐。人少的时候还好点,业务和使用人一多,系统慢得象蜗牛。而网络基础设施这几年来改造、提升得差不多了,都是百兆桌面、千兆骨干了。地市级公司内部虽然办公点分散,但都是使用电力专用光纤建设的千兆骨干的MPLSVPN技术,地市公司与网省公司是千兆或万兆专用光纤。因此其实网络基础设施还是绰绰有余。为了自证清白,上级主管部门就盟生了建一个分层分布式的网速测试系统的想法。你说网速慢,那你在客户端上打开网页,测试一下各级网速,就可能看看到底是网速慢,还是应用系统本身太垃圾。

 

思路

在网络上给出的参考方法,WEB版的大部份是客户端用JAVASCRIPT下载一个大文件,然后根据速度=总下载量/时间,得到网速;专业的开源测试工具是iperf,是c版本的,和业余的相比,专业的不只一点点。于是,了解了一下iperf的基本思路和方法,于是采用JAVA来写,利用socket直接实现通信,服务端和客户端配合,通过TCP通信的数据量和使用时间来计算网络速度,一方面效率高、减少其它因素(如HTTP协议、JAVASCRIPT加载与执行效率等)的影响;另一方面,利用applet可以实现B/S应用,客户端部署使用简单。程序代码参考了OSCHINA的JGroups项目的JPerf.java。项目名称为jperf,使用eclipse开发和测试,目前实现了基本功能(因目前只是进行验证,因此未进行完整的异常处理、验证等)。

  1 import java.io.*;
  2 import java.net.InetAddress;
  3 import java.net.ServerSocket;
  4 import java.net.Socket;
  5 import java.net.UnknownHostException;
  6 import java.text.NumberFormat;
  7 /***
  8  * Tool to measure TCP throughput, similar to iperf
  9  * @author Bela Ban
 10  * @version $Id: JPerf.java,v 1.4 2007/12/28 23:29:17 belaban Exp $
 11  */
 12 public class jperf implements Runnable{
 13     boolean client;
 14     boolean direction;//test direction:true-up test,false-down
 15     int num;
 16     InetAddress local_addr;
 17     int local_port;
 18     int remote_port;
 19     InetAddress remote_addr;
 20     int size;
 21     int receivebuf=200000;
 22     int sendbuf=200000;
 23     static  NumberFormat f;
 24     Socket client_sock;
 25                
 26     static {
 27         f=NumberFormat.getNumberInstance();
 28         f.setGroupingUsed(false);
 29         f.setMaximumFractionDigits(2);
 30     }
 31                 
 32     public jperf(){
 33     }
 34                 
 35     //实现Thread类的接口Runnable, 用于支持服务端连接的多线程
 36     @Override
 37     public void run() {
 38         // TODO Auto-generated method stub
 39         try {
 40             server_accept_data();
 41         } catch (IOException e) {
 42             // TODO Auto-generated catch block
 43             e.printStackTrace();
 44         } catch (ClassNotFoundException e) {
 45             // TODO Auto-generated catch block
 46             e.printStackTrace();
 47         }
 48                     
 49     }
 50     //用于applet和GUI调用
 51     public jperf(String remote_addr,int remote_port,int num,int size,boolean direction) throws UnknownHostException{
 52                      
 53          this.remote_addr=InetAddress.getByName(remote_addr);
 54          this.remote_port=remote_port;
 55          this.num=num;
 56          this.size=size;
 57          this.direction=direction;
 58      }
 59                 
 60     private void start(boolean client, boolean direction,int num, int size, String local_addr, int local_port,
 61                        String remote_addr, int remote_port,int receivebuf, int sendbuf) throws IOException, ClassNotFoundException {
 62         this.client=client;
 63         this.direction=direction;
 64         this.num=num;
 65         this.size=size;
 66         this.local_addr=InetAddress.getByName(local_addr);
 67         this.local_port=local_port;      
 68         this.remote_addr=InetAddress.getByName(remote_addr);
 69         this.remote_port=remote_port;
 70         this.receivebuf=receivebuf;
 71         this.sendbuf=sendbuf;
 72                     
 73         if(client) {
 74            client();
 75         }
 76         else {
 77             server();
 78         }
 79     }
 80     //客户端调用
 81     public String client() throws IOException{
 82                             
 83         System.out.println("-- creating socket to " + this.remote_addr + ":" + this.remote_port);
 84         client_sock=new Socket(this.remote_addr, remote_port);
 85                     
 86         String result="";
 87         if(sendExchangeData()==true){
 88             if(direction==true) result=sendData(num,size);
 89             else result=receiveData(num,size);
 90         }
 91         else{
 92             result="connect to server and exchange data fail!";
 93         }
 94         System.out.println(result);  
 95         client_sock.close();
 96                     
 97         return result;
 98     }
 99     //客户端向服务端发送测试 的数据参数
100     private boolean sendExchangeData() throws IOException{
101         boolean ret=true;
102                     
103         client_sock.setReceiveBufferSize(receivebuf);
104         client_sock.setSendBufferSize(sendbuf);
105         ObjectOutputStream write=new ObjectOutputStream(new BufferedOutputStream(client_sock.getOutputStream()));
106         write.writeObject(num);
107         write.flush();
108         write.writeObject(size);
109         write.flush();
110         write.writeObject(direction);
111         write.flush();
112                     
113         return ret;
114     }
115     //服务端调用
116     private void server() throws IOException, ClassNotFoundException
117     {              
118          ServerSocket srv_sock=new ServerSocket(local_port, 10, this.local_addr);
119          System.out.println("-- waiting for client on " + srv_sock.getLocalSocketAddress());
120          while(true){
121              //wait for a client connect
122              Socket client_sock=srv_sock.accept();
123              //start a new thread deal this connection:
124              jperf thread_client=new jperf();
125              thread_client.client_sock=client_sock;
126              thread_client.sendbuf=sendbuf;
127              thread_client.receivebuf=receivebuf;
128              //每一个客户端单独一个线程,支持多个客户端同时连接
129              Thread thread=new Thread(thread_client);
130              thread.start();
131          }
132                      
133     }
134     //服务器接收和发送测试 数据
135     private void server_accept_data() throws IOException, ClassNotFoundException{             
136         client_sock.setReceiveBufferSize(receivebuf);
137         client_sock.setSendBufferSize(sendbuf);
138         System.out.println("-- accepted data connection from " + client_sock.getRemoteSocketAddress());
139         ObjectInputStream in=new ObjectInputStream(new BufferedInputStream(client_sock.getInputStream()));
140                         
141         int num=0,size=0;
142         boolean direction=false;
143         num=(Integer)in.readObject();
144         size=(Integer)in.readObject();      
145         direction=(Boolean)in.readObject();
146                     
147         if(num>0 && size>0) {
148             String result;
149             if(direction==true) result=receiveData(num,size);
150             else result=sendData(num,size);
151                         
152             System.out.println(result);
153          }      
154          else{
155             System.out.println("-- invalid exchange data! ");
156          }
157          client_sock.close();
158     }
159     //发送数据,并计算测试结果
160     private String sendData(int num,int size) throws IOException
161     {     
162         System.out.println("-- sending data to "+client_sock.getRemoteSocketAddress().toString()+ " total "+num + " messages");
163         DataOutputStream out=new DataOutputStream(new BufferedOutputStream(client_sock.getOutputStream()));
164         byte[] buf=new byte[size];      
165         for(int i=0;i<buf.length;i++) buf[i]=(byte)(i%128);
166         long start=0, stop;
167         int cnt=1;
168         int incr=num/10;
169         start=System.currentTimeMillis();
170         for(int i=0; i < num; i++) {           
171             out.write(buf, 0, buf.length);
172             out.flush();
173             if(cnt % incr == 0)
174                 System.out.println("-- sent " + cnt + " messages");
175             cnt++;
176         }
177         stop=System.currentTimeMillis();
178         long diff=stop-start;
179         String result=report("发送报文至 "+client_sock.getRemoteSocketAddress().toString(),(long)num*(long)size,diff);      
180                     
181         return result;
182     }
183                 
184     //接收数据,并计算测试结果
185     private String receiveData(int num,int size) throws IOException{
186         System.out.println("-- accepted data from " + client_sock.getRemoteSocketAddress().toString()+" total "+num+" messages");
187         DataInputStream in=new DataInputStream(new BufferedInputStream(client_sock.getInputStream()));
188         byte[] buf=new byte[size];          
189         long counter=0;
190         int incr=num/10;
191         long start=0, stop;      
192         while(true) {
193             int len=in.read(buf, 0, buf.length);
194             if(len<=0) break;
195             if(start == 0)
196                 start=System.currentTimeMillis();
197             counter+=len;
198             if((counter/size) % incr == 0)
199                 System.out.println("-- received " + counter/size);
200         }          
201         stop=System.currentTimeMillis();
202         long diff=stop-start;
203         String result=report("接收报文来自 "+client_sock.getRemoteSocketAddress().toString(),counter,diff);
204                     
205         return result;
206     }
207     //计算测试结果 
208     private String report(String direction,long totalbyte, double diff)
209     {
210         StringBuilder sb=new StringBuilder();
211         double tbs=totalbyte/(1024*1024);
212         if(tbs<1000)  sb.append("\n"+direction+",测试数据总数" + f.format(tbs) + "Mbyte"+" ,用时 " + diff + "毫秒 ");
213         else{
214             tbs=tbs/1024;
215             sb.append("\n"+direction+",测试数据总数" + f.format(tbs)+ "Gbyte"+" ,用时 " + diff + "毫秒 ");
216         }
217          //tcp throughput:
218          double throughput=totalbyte / (diff / 1000.0) / 1024.0;
219          if(throughput < 1000)
220              sb.append("\n网络吞吐量: " + f.format(throughput) + "KB/秒");
221          else {
222              throughput/=1024.0;
223              sb.append("\n网络吞吐量: " + f.format(throughput) + "MB/秒");
224          }
225          //bandwidth
226          double bandwidth=totalbyte / (diff / 1000.0) / 1024.0*8;
227          if(bandwidth < 1000){
228              sb.append("\n网络带宽: " + f.format(bandwidth) + "Kb/秒");
229          }
230          else {
231             bandwidth/=1024.0;
232              if(bandwidth>1000){
233                 bandwidth/=1024;
234                 sb.append("\n网络带宽: " + f.format(bandwidth) + "Gb/秒");
235              }
236              else sb.append("\n网络带宽: " + f.format(bandwidth) + "Mb/秒");          
237          }
238          return sb.toString();
239     }
240     static void help() {
241         System.out.println("JPerf [-help] [-client] [-direction <up|down>] [-num <number of msgs] [-size <bytes>] [-local_addr <interface>] [-local_port <port]" +
242                 "[-remote_addr <IP addr>] [-remote_port <port>] [-receivebuf <bytes>] [-sendbuf <bytes>]");
243     }
244     //主程序执行入口
245     public static void main(String[] args) throws UnknownHostException {
246         boolean client=false;
247         boolean direction=false;//test direction:true-up test,false-down test
248         int num=10000;
249         int size=8192;
250         String local_addr=InetAddress.getLocalHost().getHostAddress();
251         String remote_addr=local_addr;
252         int local_port=5000;
253         int remote_port=5000;
254         int receivebuf=200000, sendbuf=200000;
255         for(int i=0; i < args.length; i++) {
256             if(args[i].equals("-client")) {
257                 client=true;
258                 continue;
259             }
260             if(args[i].equals("-num")) {
261                 num=Integer.parseInt(args[++i]);
262                 continue;
263             }
264             if(args[i].equals("-size")) {
265                 size=Integer.parseInt(args[++i]);
266                 continue;
267             }
268             if(args[i].equals("-local_addr")) {
269                 local_addr=args[++i];
270                 continue;
271             }
272             if(args[i].equals("-remote_addr")) {
273                 remote_addr=args[++i];
274                 continue;
275             }
276             if(args[i].equals("-local_port")) {
277                 local_port=Integer.parseInt(args[++i]);
278                 continue;
279             }
280             if(args[i].equals("-remote_port")) {
281                 remote_port=Integer.parseInt(args[++i]);
282                 continue;
283             }
284             if(args[i].equals("-receivebuf")) {
285                 receivebuf=Integer.parseInt(args[++i]);
286                 continue;
287             }
288             if(args[i].equals("-sendbuf")) {
289                 sendbuf=Integer.parseInt(args[++i]);
290                 continue;
291             }
292             if(args[i].equals("-direction")) {
293                  String value=args[++i];
294                  if(value.toLowerCase().equals("up")) direction=true;
295                  else direction=false;
296                              
297                  continue;
298             }
299             help();
300             return;
301         }
302         try {
303             new jperf().start(client, direction,num, size, local_addr, local_port, remote_addr, remote_port, receivebuf, sendbuf);
304         }
305         catch(IOException e) {
306             e.printStackTrace();
307         } catch (ClassNotFoundException e) {
308             e.printStackTrace();
309         }
310     } 
311 }
View Code

编译代码:javac jperf.java

在服务端执行:java jperf,启动后默认在5000端口上进行监听。

在客户端执行:java jperf -client -remote_addr x.x.x.x,默认参数为数据报文数10000,数据包大小8192(针对默认的WINDOWS系统的TCP窗口),端口5000,方向为测试下行。

Java jperf -client -remote_addr x.x.x.x -direction up测试上行。

经过测试,两台通过百兆口交换机连接的计算机,吞吐量为11.3MB/s,带宽为90.4Mb/s左右。

 

本文出自 “一个业余程序员的历程” 博客,请务必保留此出处http://hancool.blog.51cto.com/1836252/1352228

 

相关文章
|
29天前
|
网络协议 Shell Linux
【Shell 命令集合 网络通讯 】⭐⭐⭐Linux 测试与目标主机之间的网络连接ping 命令 使用指南
【Shell 命令集合 网络通讯 】⭐⭐⭐Linux 测试与目标主机之间的网络连接ping 命令 使用指南
42 1
|
1月前
|
Java 计算机视觉
java实现人脸识别源码【含测试效果图】——前台页面层(login.jsp)
java实现人脸识别源码【含测试效果图】——前台页面层(login.jsp)
12 0
|
18天前
|
Web App开发 前端开发 Java
《手把手教你》系列技巧篇(九)-java+ selenium自动化测试-元素定位大法之By name(详细教程)
【4月更文挑战第1天】 这篇教程介绍了如何使用Selenium Webdriver通过name属性来定位网页元素,作为系列教程的一部分,之前讲解了id定位,后续还会有其他六种定位方法。文中以百度搜索为例,详细说明了定位搜索框(name=&quot;wd&quot;)并输入关键词“北京宏哥”的步骤,包括手动操作流程、编写自动化脚本以及代码实现。此外,还提供了查看和理解Selenium源码的方法,强调了`open implementation`选项用于查看方法的具体实现。整个过程旨在帮助读者学习Selenium的元素定位,并实践自动化测试。
38 0
|
30天前
|
Web App开发 存储 JavaScript
《手把手教你》系列技巧篇(八)-java+ selenium自动化测试-元素定位大法之By id(详细教程)
【2月更文挑战第17天】本文介绍了Web自动化测试的核心——元素定位。文章首先强调了定位元素的重要性,指出找不到元素则无法进行后续操作。Selenium提供八种定位方法,包括By id、name、class name等。其中,By id是最简单快捷的方式。文章还阐述了自动化测试的步骤:定位元素、操作元素、验证结果和记录测试结果。此外,讨论了如何选择定位方法,推荐优先使用简单稳定的方式,如id,其次考虑其他方法。最后,作者提供了Chrome浏览器的开发者工具作为定位元素的工具,并给出了通过id定位的代码示例。
51 0
|
13天前
|
前端开发 Java 测试技术
《手把手教你》系列技巧篇(十二)-java+ selenium自动化测试-元素定位大法之By link text(详细教程)
【4月更文挑战第4天】本文介绍了link text在自动化测试中的应用。Link text是指网页中链接的文字描述,点击可跳转至其他页面。文章列举了8种常用的定位方法,其中着重讲解了link text定位,并通过实例展示了如何使用Java代码实现点击百度首页的“奥运奖牌榜 最新排名”链接,进入相应页面。如果link text不准确,则无法定位到元素,这说明linkText是精准匹配,而非模糊匹配。文章还提到了partial link text作为link text的模糊匹配版本,将在后续内容中介绍。
35 4
|
12天前
|
Java 测试技术
SpringBoot整合单元测试&&关于SpringBoot单元测试找不到Mapper和Service报java.lang.NullPointerException的错误
SpringBoot整合单元测试&&关于SpringBoot单元测试找不到Mapper和Service报java.lang.NullPointerException的错误
16 0
|
9天前
|
Java Maven
【Java报错】显示错误“Error:java: 程序包org.springframework.boot不存在“
【Java报错】显示错误“Error:java: 程序包org.springframework.boot不存在“
32 3
|
12天前
|
XML 前端开发 Java
《手把手教你》系列技巧篇(十四)-java+ selenium自动化测试-元素定位大法之By xpath上卷(详细教程)
【4月更文挑战第6天】按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath。xpath 的定位方法, 非常强大。使用这种方法几乎可以定位到页面上的任意元素。xpath 是XML Path的简称, 由于HTML文档本身就是一个标准的XML页面,所以我们可以使用Xpath 的用法来定位页面元素。XPath 是XML 和Path的缩写,主要用于xml文档中选择文档中节点。基于XML树状文档结构,XPath语言可以用在整棵树中寻找指定的节点。
42 0
Java 测试技术
5 0
|
1天前
|
前端开发 JavaScript Java
《手把手教你》系列技巧篇(二十五)-java+ selenium自动化测试-FluentWait(详细教程)
【4月更文挑战第17天】其实今天介绍也讲解的也是一种等待的方法,有些童鞋或者小伙伴们会问宏哥,这也是一种等待方法,为什么不在上一篇文章中竹筒倒豆子一股脑的全部说完,反而又在这里单独写了一篇。那是因为这个比较重要,所以宏哥专门为她量身定制了一篇。FluentWait是Selenium中功能强大的一种等待方式,翻译成中文是流畅等待的意思。在介绍FluentWait之前,我们来讨论下为什么需要设置等待,我们前面介绍了隐式等待和显式等待。
14 3