package org.jgroups.tests.perf; import java.io.*; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.text.NumberFormat; /** * Tool to measure TCP throughput, similar to iperf * @author Bela Ban */ public class JPerf { boolean sender; int num; InetAddress local_addr; int local_port; int remote_port; InetAddress remote_addr; int size=1000; int incr=1000; static NumberFormat f; static { f=NumberFormat.getNumberInstance(); f.setGroupingUsed(false); f.setMaximumFractionDigits(2); } private void start(boolean sender, int num, int size, String local_addr, int local_port, String remote_addr, int remote_port, int receivebuf, int sendbuf) throws IOException { this.sender=sender; this.num=num; this.size=size; this.local_addr=InetAddress.getByName(local_addr); this.local_port=local_port; this.remote_addr=InetAddress.getByName(remote_addr); this.remote_port=remote_port; incr=num / 10; if(sender) { System.out.println("-- creating socket to " + this.remote_addr + ":" + this.remote_port); Socket sock=new Socket(this.remote_addr, remote_port); sock.setReceiveBufferSize(receivebuf); sock.setSendBufferSize(sendbuf); DataOutputStream out=new DataOutputStream(new BufferedOutputStream(sock.getOutputStream())); byte[] buf=new byte[size]; int cnt=1; System.out.println("-- sending " + num + " messages"); for(int i=0; i < num; i++) { out.write(buf, 0, buf.length); out.flush(); if(cnt % incr == 0) System.out.println("-- sent " + cnt + " messages"); cnt++; } } else { ServerSocket srv_sock=new ServerSocket(local_port, 10, this.local_addr); System.out.println("-- waiting for " + num + " messages on " + srv_sock.getLocalSocketAddress()); Socket client_sock=srv_sock.accept(); client_sock.setReceiveBufferSize(receivebuf); client_sock.setSendBufferSize(sendbuf); System.out.println("-- accepted connection from " + client_sock.getRemoteSocketAddress()); DataInputStream in=new DataInputStream(new BufferedInputStream(client_sock.getInputStream())); byte[] buf=new byte[size]; int counter=0; long start=0, stop; while(counter < num) { in.readFully(buf, 0, buf.length); if(start == 0) start=System.currentTimeMillis(); counter++; if(counter % incr == 0) System.out.println("-- received " + counter); } stop=System.currentTimeMillis(); long diff=stop-start; double msgs_sec=(counter / (diff / 1000.0)); System.out.println("\nreceived " + counter + " messages in " + diff + "ms (" + f.format(msgs_sec) + " msgs/sec)"); double throughput=num * size / (diff / 1000.0) / 1000.0; if(throughput < 1000) System.out.println("throughput: " + f.format(throughput) + "KB/sec"); else { throughput/=1000.0; System.out.println("throughput: " + f.format(throughput) + "MB/sec"); } } } static void help() { System.out.println("JPerf [-help] [-sender] [-num <number of msgs] [-size <bytes>] [-local_addr <interface>] [-local_port <port]" + "[-remote_addr <IP addr>] [-remote_port <port>] [-receivebuf <bytes>] [-sendbuf <bytes>]"); } public static void main(String[] args) { boolean sender=false; int num=100000; String local_addr="127.0.0.1"; int local_port=5000; int size=1000; int remote_port=10000; int receivebuf=200000, sendbuf=200000; String remote_addr="127.0.0.1"; for(int i=0; i < args.length; i++) { if(args[i].equals("-sender")) { sender=true; continue; } if(args[i].equals("-num")) { num=Integer.parseInt(args[++i]); continue; } if(args[i].equals("-size")) { size=Integer.parseInt(args[++i]); continue; } if(args[i].equals("-local_addr")) { local_addr=args[++i]; continue; } if(args[i].equals("-remote_addr")) { remote_addr=args[++i]; continue; } if(args[i].equals("-local_port")) { local_port=Integer.parseInt(args[++i]); continue; } if(args[i].equals("-remote_port")) { remote_port=Integer.parseInt(args[++i]); continue; } if(args[i].equals("-receivebuf")) { receivebuf=Integer.parseInt(args[++i]); continue; } if(args[i].equals("-sendbuf")) { sendbuf=Integer.parseInt(args[++i]); continue; } help(); return; } try { new JPerf().start(sender, num, size, local_addr, local_port, remote_addr, remote_port, receivebuf, sendbuf); } catch(IOException e) { e.printStackTrace(); } } }