KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tomcat > jni > Echo


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.tomcat.jni;
18
19 import java.util.Properties JavaDoc;
20
21 import java.io.*;
22 import java.net.*;
23 import java.lang.*;
24
25 /** Echo server example
26  *
27  * @author Mladen Turk
28  * @version $Revision: 1.1 $, $Date: 2005/02/05 12:34:47 $
29  */

30
31 public class Echo {
32
33     public static String JavaDoc echoEcho = null;
34     public static String JavaDoc echoAddr = null;
35     public static int echoPort = 0;
36     public static int echoNmax = 0;
37     public static int echoNrun = 0;
38     public static long echoPool = 0;
39
40     private static Poller echoPoller = null;
41     private static Acceptor echoAcceptor = null;
42
43     private static Object JavaDoc threadLock = new Object JavaDoc();
44
45     static {
46
47         try {
48             InputStream is = Echo.class.getResourceAsStream
49                 ("/org/apache/tomcat/jni/Echo.properties");
50             Properties JavaDoc props = new Properties JavaDoc();
51             props.load(is);
52             is.close();
53             echoAddr = props.getProperty("echo.ip", "127.0.0.1");
54             echoPort = Integer.decode(props.getProperty("echo.port", "23"));
55             echoNmax = Integer.decode(props.getProperty("echo.max", "1"));
56         }
57         catch (Throwable JavaDoc t) {
58             ; // Nothing
59
}
60     }
61
62     /* Acceptor thread. Listens for new connections */
63     private class Acceptor extends Thread JavaDoc {
64         private long serverSock = 0;
65         private long inetAddress = 0;
66         private long pool = 0;
67         public Acceptor() {
68             try {
69
70                 pool = Pool.create(Echo.echoPool);
71                 System.out.println("Accepting: " + Echo.echoAddr + ":" +
72                                    Echo.echoPort);
73                 inetAddress = Address.info(Echo.echoAddr, Socket.APR_INET,
74                                            Echo.echoPort, 0,
75                                            pool);
76                 serverSock = Socket.create(Socket.APR_INET, Socket.SOCK_STREAM,
77                                            Socket.APR_PROTO_TCP, pool);
78                 Socket.bind(serverSock, inetAddress);
79                 Socket.listen(serverSock, 5);
80             }
81             catch( Exception JavaDoc ex ) {
82                 ex.printStackTrace();
83             }
84         }
85
86         public void run() {
87             int i = 0;
88             try {
89                 while (true) {
90                     long clientSock = Socket.accept(serverSock, pool);
91                     System.out.println("Accepted id: " + i);
92                     Worker worker = new Worker(clientSock, i++,
93                                                this.getClass().getName());
94                     Echo.incThreads();
95                     worker.start();
96                 }
97             }
98             catch( Exception JavaDoc ex ) {
99                 ex.printStackTrace();
100             }
101         }
102     }
103
104     /* Poller thread. Listens for new recycled connections */
105     private class Poller extends Thread JavaDoc {
106         private long serverPollset = 0;
107         private long pool = 0;
108         private int nsocks = 0;
109         public Poller() {
110             try {
111
112                 pool = Pool.create(Echo.echoPool);
113                 serverPollset = Poll.create(16, pool, 0);
114             }
115             catch( Exception JavaDoc ex ) {
116                 ex.printStackTrace();
117             }
118         }
119
120         public void add(long socket, int workerId) {
121             int rv = Poll.add(serverPollset, socket, workerId,
122                               Poll.APR_POLLIN, 0);
123             if (rv == Status.APR_SUCCESS) {
124                 System.out.println("Added worker " + workerId + " to pollset");
125                 nsocks++;
126             }
127         }
128
129         public void remove(long socket, int workerId) {
130             int rv = Poll.remove(serverPollset, socket);
131             if (rv == Status.APR_SUCCESS) {
132                nsocks--;
133                System.out.println("Removed worker " + workerId + " from pollset");
134             }
135             else {
136                System.out.println("Failed removing worker " + workerId + " from pollset");
137             }
138         }
139
140         public void run() {
141             while (true) {
142                 try {
143                     if (nsocks < 1) {
144                         Thread.sleep(1);
145                         continue;
146                     }
147                     long [] desc = new long[16];
148                     /* USe 1 second poll timeout */
149                     int rv = Poll.poll(serverPollset, 1000000, desc);
150                     for (int n = 0; n < rv; n++) {
151                         long clientSock = Poll.socket(desc[n]);
152                         int workerId = (int)Poll.data(desc[n]);
153                         remove(clientSock, workerId);
154                         Worker worker = new Worker(clientSock, workerId,
155                                                    this.getClass().getName());
156                         Echo.incThreads();
157                         worker.start();
158                     }
159                 }
160                 catch(Error JavaDoc err ) {
161                     if (Status.APR_STATUS_IS_TIMEUP(err.getError())) {
162                         /* TODO: deal with timeout */
163                     }
164                     else {
165                         err.printStackTrace();
166                         break;
167                     }
168                 }
169                 catch( Exception JavaDoc ex ) {
170                     ex.printStackTrace();
171                     break;
172                 }
173             }
174         }
175     }
176
177     private class Worker extends Thread JavaDoc {
178         private int workerId = 0;
179         private long clientSock = 0;
180         private byte [] wellcomeMsg = null;
181         public Worker(long clientSocket, int workerId, String JavaDoc from) {
182             this.clientSock = clientSocket;
183             this.workerId = workerId;
184             wellcomeMsg = ("Echo server id: " + this.workerId + " from " +
185                            from + "\r\n").getBytes();
186         }
187
188         public void run() {
189             boolean doClose = false;
190             try {
191                 Socket.send(clientSock, wellcomeMsg, wellcomeMsg.length);
192                 /* Do a blocking read byte at a time */
193                 byte [] buf = new byte[1];
194                 while (Socket.recv(clientSock, buf, 1) == 1) {
195                     if (buf[0] == '\n')
196                         break;
197                     else if (buf[0] == 'Q') {
198                         doClose = true;
199                         break;
200                     }
201                 }
202                 if (doClose) {
203                     try {
204                         byte [] msg = ("Bye from worker: " + workerId + "\r\n").getBytes();
205                         Socket.send(clientSock, msg, msg.length);
206                     } catch(Exception JavaDoc e) { }
207
208                     Socket.close(clientSock);
209                 }
210                 else {
211                     try {
212                         byte [] msg = ("Recycling worker: " + workerId + "\r\n").getBytes();
213                         Socket.send(clientSock, msg, msg.length);
214                     } catch(Exception JavaDoc e) { }
215                     /* Put the socket to the keep-alive poll */
216                     Echo.echoPoller.add(clientSock, workerId);
217                 }
218             } catch (Exception JavaDoc e) {
219                 Socket.close(clientSock);
220                 e.printStackTrace();
221             }
222             Echo.decThreads();
223             System.out.println("Worker: " + workerId + " finished");
224         }
225     }
226
227     public Echo()
228     {
229         int i;
230         echoPool = Pool.create(0);
231         echoAcceptor = new Acceptor();
232         echoAcceptor.start();
233         echoPoller = new Poller();
234         echoPoller.start();
235
236     }
237
238     public static void incThreads() {
239         synchronized(threadLock) {
240             echoNrun++;
241         }
242     }
243
244     public static void decThreads() {
245         synchronized(threadLock) {
246             echoNrun--;
247         }
248     }
249
250     public static void main(String JavaDoc [] args) {
251         try {
252             Library.initialize(null);
253             System.out.println("Starting Native Echo server example on port " +
254                                echoAddr + ":" + echoPort);
255             Echo echo = new Echo();
256         } catch (Exception JavaDoc e) {
257             e.printStackTrace();
258         }
259
260     }
261 }
262
Popular Tags