Source code: raining/client/SocketBlaster.java
1 /*
2 * $Author: rahul_kumar $
3 * $Id: SocketBlaster.java,v 1.7 2003/10/08 15:05:19 rahul_kumar Exp $
4 *
5 * Java 1.4.2 (or above) based NIO socket framework.
6 * Copyright (C) 2003 Rahul Kumar. All rights reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24 package raining.client;
25 import raining.core.*;
26 import java.net.URL;
27 import org.apache.commons.cli.*;
28 import java.io.*;
29 import java.util.*;
30
31 /**
32 * A Load Tester program that generates a high number of http requests
33 * to send to one URL.
34 * FIXME: Not working with proxies any longer.
35 *
36 * Command line for:
37 * - file to take URLs from, usually these would be different URLs on
38 * one server
39 * - use proxy, server, port, authstring
40 *
41 * FOr Testing or loading (this should go into another extends)
42 * - how many concurrent connections (A)
43 * - how long to keep hitting URL
44 * - any pause between A's
45 * - max hits
46 *
47 * We shd be able to inherit cl parsing and add/override our options ?
48 * Many things will have to be done ONCE not each time, since URLs are
49 * the same - URL parse, GET, base64 etc.
50 */
51
52 public class SocketBlaster {
53
54 static int maxhits ;
55 static long interval = 15 ; // 15 seconds between bursts
56 static long maxtime ; // 5*60*1000; // 5 minutes in millis
57 static int idealconnections = 0;
58
59 public static void main (String args[]){
60
61 String urlarray[] = null;
62 String proxyServer = null;
63 int proxyPort = 8080;
64 String proxyAuth = null;
65 String proxyBase64 = null;
66 String filename = null;
67 boolean useProxy = false;
68
69 ClientParser clp = new ClientParser(args, "SocketBlaster");
70 Options options = clp.getOptions();
71 options.addOption( "n", "maxhits", true, "How many connections to send" );
72 options.addOption( "i", "interval", true, "How much interval between blasts" );
73 options.addOption( "t", "maxtime", true, "How long to keep sending (seconds)" );
74 options.addOption( "x", "load", true, "how many urls to keep bytes read for" );
75 clp.setOptionProcessor( new OptionProcessor(){
76 public void processOpt( Option obj ,String opt, String longOpt, String value){
77 if (opt.equals("x")){
78 int load = Integer.parseInt(value) ;
79 if (load > 0)
80 SBHttpClient.setLoadArray( load );
81 }
82 else
83 if (opt.equals("n")){
84 maxhits = Integer.parseInt(value);
85 System.out.println( "Max hits is: "+ maxhits );
86 }
87 else
88 if (opt.equals("t")){
89 try {
90 maxtime = Long.parseLong(value);
91 maxtime *= 1000; // millis
92 } catch (Exception exc) { System.err.println( ">>> 79 EXC:"+ exc.toString()); }
93 }
94 else
95 if (opt.equals("i")){
96 try {
97 interval = Long.parseLong(value);
98 interval *= 1000; // millis
99 } catch (Exception exc) { System.err.println( ">>> 79 EXC:"+ exc.toString()); }
100 }
101 System.out.println( "Max time is: "+ maxtime + " millis.");
102 }
103 });
104
105 clp.parse();
106
107 urlarray = clp.getUrlArray();
108 // the following gets still need to be moved off, this is adding
109 // to the work one has to do, even after using clp.
110 useProxy = clp.getUseProxy();
111 //System.out.println( "Using proxy: "+ useProxy);
112
113 if (useProxy){
114 SBHttpClient.setProxy(clp.getProxyServer(), clp.getProxyPort());
115
116 if (clp.getProxyAuth() != null)
117 SBHttpClient.setProxyAuthString(clp.getProxyAuth());
118 else
119 System.err.println( "warning: Auth String not passed for connecting to proxy !");
120 } // proxy settings
121
122
123
124 if (args.length == 0 || urlarray.length == 0)
125 {
126 // automatically generate the help statement
127 clp.printhelp(options);
128 // add help options specific to this class
129 System.err.println( " java raining/client/SocketBlaster -n 1000 http://localhost/index.html");
130 System.err.println( " java raining/client/SocketBlaster -t 1000 http://localhost/examples/jsp/index.jsp");
131 System.exit(-1);
132 }
133
134 try {
135
136 // START WORK
137 // currently inefficient
138 // base64 conv to be done only once
139 // TODO see what all can be done once only
140 // URL stripping can also be done once since we are sending
141 // to the same URL
142 // GETString to be made once for all
143 //
144 if (urlarray.length >0){
145 SocketBlaster sb = new SocketBlaster();
146 sb.setURLArray(urlarray);
147 if (maxhits > 0) sb.setMaxHits(maxhits);
148 if (maxtime > 0) sb.setMaxTime(maxtime);
149
150 sb.start();
151 }
152
153 } catch (Exception exc) { System.err.println( " SocketB 145 EXC:"+ exc.toString()); exc.printStackTrace(); }
154
155 }
156
157 // long maxtime = 0;
158 // int maxhits = 0;
159 long starttime;
160 String urlarray[] = null;
161 Timer timer = null;
162
163
164 /** Empty Constructor
165 */
166 public SocketBlaster ()
167 //throws java.net.MalformedURLException, java.io.IOException, Exception
168 {
169 timer = new Timer();
170 }
171 public void setMaxTime(long maxtime){
172 maxtime = maxtime;
173 //this.maxtime = maxtime;
174 }
175 public void setMaxHits(int maxhits){
176 //this.maxhits = maxhits;
177 maxhits = maxhits;
178 }
179 public void setURLArray(String[] urlarray){
180 this.urlarray = urlarray;
181 }
182 /** start the socket blaster.
183 */
184 public void start() throws java.io.IOException, Exception{
185
186 if (maxhits < 1 && maxtime < 1) {
187 System.err.println( "Nothing to do!");
188 return;
189 }
190 // currntly will hit maxhits * urlarray.length times
191 final int len = urlarray.length;
192 final URLDetails urld[] = new URLDetails[len];
193
194 // put the get strings in an array
195 try {
196 for( int i = 0; i < len; i++ ){
197 urld[i]= HttpClient.makeGETString(urlarray[i]);
198 }
199 } catch (java.net.MalformedURLException exc) { System.err.println( "188 EXC:"+ exc.toString()); }
200
201 //SBHttpClient.setLoadArray(len * maxhits);
202 final int fmaxhits = maxhits;
203 TimerTask task = new TimerTask(){
204 long counter = 0;
205 public void run () {
206 System.err.println( ">> SENT:"+ SBHttpClient.totalsent +
207 " RCVD:"+ SBHttpClient.totalrcvd+
208 " IDEAL SENT:"+ idealconnections +
209 " Connects:" + NioSocket.conncount +
210 " Reads:" + NioSocket.readcount +
211 " Active:" + NioSocket.activeSocketCount
212 );
213 idealconnections += (fmaxhits * len);
214 try {
215 for( int j = 0; j < fmaxhits; j++ ){
216 for( int i = 0; i < len; i++ ){
217 //System.out.println( "URL: "+urlarray[i]);
218 SBHttpClient h = new SBHttpClient ();
219 //System.out.println("SB url 218:"+ urld[i].GETString);
220 h.setGETString( urld[i].GETString);
221 if ( useProxy){
222 //h.setProxy(proxyServer, proxyPort);
223 } else {
224 h.setHostPort(urld[i].host, urld[i].port);
225 }
226
227 h.push();
228 //j++;
229 }
230 }
231 System.err.println( ">> TASK: Burst over."+ (++counter));
232 System.err.println( "sent:"+ SBHttpClient.totalsent +
233 " rcvd:"+ SBHttpClient.totalrcvd +
234 " reset:"+ NioSocket.crcount +
235 " timeout:"+ NioSocket.ctcount +
236 " Active:" + NioSocket.activeSocketCount +
237 " Connects:" + NioSocket.conncount +
238 " Reads:" + NioSocket.readcount +
239 " rcv+lost:"+ (SBHttpClient.totalrcvd + NioSocket.ctcount + NioSocket.crcount)
240 );
241 } catch (Exception exc) { System.err.println( "SBL: Task Run 207 EXC:"+ exc.toString());
242 System.err.println(">>> Active count:" + NioSocket.activeSocketCount);
243 exc.printStackTrace(); }
244 }
245 };
246 timer.schedule( task, (long) 1000, (long) interval );
247
248 // should this come at end or at start ??? if 10000 urls are
249 // created this could miss out on connect events!!!
250 starttime = System.currentTimeMillis();
251 //NioSocket.stopWhenIdle(true);
252 NioSocket.start();
253 // it comes here only after start returns which means i cant
254 // keep sending more at intervals
255 //System.out.println("Socket count: "+ NioSocket.socketCount());
256 // SBH should have an atexit atstartup handler also.
257 // next line is again a dirty kludge
258 int bytesread[] = SBHttpClient.getLoadArray();
259 if (bytesread != null) {
260 for( int i = 0; i < bytesread.length; i++ ){
261 if (bytesread[i] == 0)
262 System.err.println( i+". "+ bytesread[i] );
263 }
264 }
265 }
266
267 /** we still need to know this, since we have to send the host and
268 * port for non-proxy programes.
269 * */
270 static boolean useProxy = false;
271
272
273
274
275 } // end of class
276
277
278