KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > test > TestService


1 package test;
2 import java.io.*;
3 import java.net.*;
4
5 /**
6   Server to used perform tests for SOCKS library.
7 */

8 public class TestService implements Runnable JavaDoc{
9   static final String JavaDoc chargenSequence = " !\"#$%&'()*+,-./0123456789:;<=>?@"+
10   "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefg";
11
12   static final String JavaDoc serviceNames[] = {"echo","discard","chargen","connect"};
13   static final int servicePorts[] = {5678,5679,5680,5681};
14
15   static final int ECHO = 0;
16   static final int DISCARD = 1;
17   static final int CHARGEN = 2;
18   static final int CONNECT = 3;
19
20   static final int BUF_SIZE = 1024;
21
22   static final int CHARGEN_WAIT = 1000; //1 second
23
static final int MAX_WAIT = 60000; //1 minute
24

25   static PrintStream log = null;
26
27   //Class constants
28
Socket s;
29   int service;
30
31   /**
32    Creates new TestService object, which will perform particular
33    service on given socket.
34
35    @param s Socket on which to perform service.
36    @param service Service which to provide.
37   */

38   public TestService(Socket s, int service){
39     this.s = s;
40     this.service = service;
41   }
42
43   /**
44    Default constructor.
45   */

46   public TestService(){
47     this.s = null;
48     this.service = -1;
49   }
50
51   public void run(){
52      try{
53        serve(s,service);
54      }catch(IOException ioe){
55      log("Exception:"+ioe);
56      ioe.printStackTrace();
57      }
58      try{ s.close();}catch(IOException ioe){}
59   }
60
61   //Static functions
62
/////////////////
63

64   /**
65    Maps service name to the integer id, does it in simple
66    linear search manner.
67    @param serviceName Name of the service whose id one needs.
68    @return Integer identifier for this servuce, or -1, if service
69            can't be found.
70   */

71   static public int getServiceId(String JavaDoc serviceName){
72      serviceName = serviceName.toLowerCase();
73      for(int i = 0;i < serviceNames.length;++i)
74         if(serviceName.equals(serviceNames[i]))
75            return i;
76
77      //Couldn't find one.
78
return -1;
79   }
80
81   /**
82     Performs given service on given socket.
83     <p>
84     Simply looks up and calls associated method.
85     @param s Socket on which to perform service.
86     @param service Id of the service to perform.
87     @return true if service have been found, false otherwise.
88   */

89   static public boolean serve(Socket s, int service) throws IOException{
90     switch(service){
91       case ECHO:
92         echo(s);
93       break;
94       case DISCARD:
95         discard(s);
96       break;
97       case CHARGEN:
98         chargen(s,CHARGEN_WAIT,MAX_WAIT);
99       break;
100       case CONNECT:
101         connect(s);
102       break;
103       default:
104          log("Unknown service:"+service);
105      return false;
106     }
107      return true;
108   }
109   /**
110     Echos any input on the socket to the output.
111     Echo is being done line by line.
112     @param s Socket on which to perform service.
113   */

114   static public void echo(Socket s) throws IOException{
115     BufferedReader in = new BufferedReader(new InputStreamReader(
116                            s.getInputStream()));
117     OutputStream out = s.getOutputStream();
118
119     log("Starting \"echo\" on "+s);
120
121     String JavaDoc line = in.readLine();
122     while(line != null){
123        out.write((line+"\n").getBytes());
124        log(line);
125        line = in.readLine();
126     }
127
128     log("Echo done.");
129   }
130
131   /**
132     Reads input from the socket, and does not write anything back.
133     logs input in line by line fashion.
134     @param s Socket on which to perform service.
135   */

136   static public void discard(Socket s) throws IOException{
137     BufferedReader in = new BufferedReader(new InputStreamReader(
138                            s.getInputStream()));
139     log("Starting discard on "+s);
140
141     String JavaDoc line = in.readLine();
142     while(line != null){
143        log(line);
144        line = in.readLine();
145     }
146
147     log("Discard finished.");
148   }
149
150   /**
151     Generates characters and sends them to the socket.
152     <p>
153     Unlike usual chargen (port 19), each next line of the generated
154     output is send after increasingly larger time intervals. It starts
155     from wait_time (ms), and each next time wait time is doubled.
156     Eg. 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 ... well
157     you got the idea.
158     <p>
159     It starts if either connection is clsoed or the wait time grows
160     bigger than max_wait.
161
162     @param s Socket on which to perform service.
163     @param wait_time Time in ms, from which timing sequence should begin.
164     @param max_wait Time in ms, after reaching timeout greater than this
165             value, chargen will stop.
166   */

167   static public void chargen(Socket s,long wait_time,long max_wait)
168              throws IOException{
169     byte[] buf = chargenSequence.getBytes();
170     int pos = 0;
171     OutputStream out = s.getOutputStream();
172     InputStream in = s.getInputStream();
173     s.setSoTimeout(100); //0.1 ms
174

175     log("Starting \"chargen\" on "+s);
176     while(true){
177        log("Sending message.");
178        out.write(buf,pos,buf.length - pos);
179        out.write(buf,0,pos);
180        out.write("\n".getBytes());
181        pos++;
182        try{
183       if(wait_time > max_wait) break;
184
185       log("Going to sleep for "+wait_time+" ms.");
186           Thread.currentThread().sleep(wait_time);
187       wait_time *= 2;
188       if(in.read() < 0) break; //Connection closed
189
}catch(InterruptedException JavaDoc ie){
190        }catch(InterruptedIOException ioe){
191        }
192     }
193     log("Chargen finished.");
194   }
195
196   /**
197     Models connect back situation.
198     <p>
199     Reads a line from the socket connection, line should be in the
200     form port service_id. Connects back to the remote host to port
201     specified in the line, if successful performs a service speciefied
202     by id on that new connection. If accept was successful closes the
203     control connection, else outputs error message, and then closes
204     the connection.
205
206     @param s Control connection.
207   */

208   static public void connect(Socket s)throws IOException{
209     String JavaDoc line = null;
210     Socket sock;
211     int port;
212     int service_id;
213
214     BufferedReader in = new BufferedReader(new InputStreamReader(
215                            s.getInputStream()));
216     OutputStream out = s.getOutputStream();
217
218     log("Starting \"connect\" on "+s);
219     line = in.readLine();
220     if(line == null) return; //They closed connection
221

222     java.util.StringTokenizer JavaDoc st = new java.util.StringTokenizer JavaDoc(line);
223     if(st.countTokens() < 2){ //We need at least 'port' and "id"
224
out.write("Expect: port serviceId.\n".getBytes());
225        log("Invalid arguments.");
226        return;
227     }
228     try{
229        port = Integer.parseInt(st.nextToken());
230        service_id = Integer.parseInt(st.nextToken());
231     }catch(NumberFormatException JavaDoc nfe){
232        out.write("Expect: port serviceId.\n".getBytes());
233        log("Invalid arguments.");
234        return;
235     }
236     try{
237       log("Connecting to "+s.getInetAddress()+":"+port);
238       sock = new Socket(s.getInetAddress(),port);
239     }catch(IOException ioe){
240       out.write(("Connect to "+s.getInetAddress()+
241          ":"+port+" failed").getBytes());
242       log("Connect failed.");
243       return;
244     }
245     s.close();
246     log("About to serve "+service_id);
247     serve(sock,service_id);
248   }
249
250   /**
251     Pipes data from the input stream to the output.
252     @param in Input stream.
253     @param out Output stream.
254   */

255   static public void pipe(InputStream in, OutputStream out)
256                           throws IOException{
257     byte[] buf = new byte[BUF_SIZE];
258     int bread = 0;
259     while(bread >= 0){
260        bread = in.read(buf);
261        out.write(buf,0,bread);
262     }
263   }
264
265   /**
266     Performs logging.
267   */

268   static synchronized void log(String JavaDoc s){
269      if(log != null) log.println(s);
270   }
271
272 }
273
Popular Tags