ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/clientinterface/TCPControlHandler.java
Revision: 1.9
Committed: Sat Jan 27 23:30:40 2001 UTC (23 years, 4 months ago) by tdb
Branch: MAIN
Changes since 1.8: +63 -22 lines
Log Message:
All of these classes have been javadoc'd and commented.

File Contents

# Content
1 //---PACKAGE DECLARATION---
2 package uk.ac.ukc.iscream.clientinterface;
3
4 //---IMPORTS---
5 import uk.ac.ukc.iscream.util.*;
6 import uk.ac.ukc.iscream.componentmanager.*;
7 import uk.ac.ukc.iscream.core.*;
8 import java.net.Socket;
9 import java.net.ServerSocket;
10 import java.io.InputStream;
11 import java.io.OutputStream;
12 import java.io.IOException;
13 import java.io.BufferedReader;
14 import java.io.PrintWriter;
15 import java.io.InputStreamReader;
16
17
18 /**
19 * Acts as a Control Handler to a TCP based client.
20 *
21 * @author $Author: tdb1 $
22 * @version $Id: TCPControlHandler.java,v 1.8 2001/01/24 00:55:33 tdb1 Exp $
23 */
24 class TCPControlHandler extends Thread {
25
26 //---FINAL ATTRIBUTES---
27
28 /**
29 * The current CVS revision of this class
30 */
31 public final String REVISION = "$Revision: 1.8 $";
32
33 /**
34 * This is our protocol version. It is hardcoded to ensure
35 * that it doesn't get accidently changed. A change to the
36 * protocol would also require changing this classes code !
37 */
38 public static final String PROTOVER = "PROTOCOL 1.1";
39
40 //---STATIC METHODS---
41
42 //---CONSTRUCTORS---
43
44 /**
45 * Construct a new TCPControlHandler, and setup the reader
46 * and writer for the new Socket.
47 *
48 * @param socket The Socket connected to the new Client
49 * @param packetSorter A reference to the PacketSorter in the component
50 */
51 public TCPControlHandler(Socket socket, PacketSorter packetSorter) throws IOException {
52 _socket = socket;
53 _packetSorter = packetSorter;
54 // setup the reader & writer
55 _socketIn = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
56 _socketOut = new PrintWriter(_socket.getOutputStream());
57 // set the default hostlist to "all host", for backward compatibility
58 _hostList = "";
59 _logger.write(toString(), Logger.SYSINIT, "created");
60 }
61
62 //---PUBLIC METHODS---
63
64 /**
65 * This method initiates the thread, setting things up, and then
66 * reading commands from the Client. It handles setting up of the
67 * DataHandler, and clean shutting down.
68 */
69 public void run() {
70 boolean run = true;
71 // Tell the client our protocol, and ask it for it's name
72 try {
73 _socketOut.println(PROTOVER);
74 _socketOut.flush();
75 _clientName = _socketIn.readLine();
76 _socketOut.println("OK");
77 _socketOut.flush();
78 }
79 catch(IOException e) {
80 _logger.write(toString(), Logger.FATAL, "Fatal error, shutdown pending");
81 run=false;
82 }
83
84 _logger.write(toString(), Logger.SYSMSG, "Client has connected: "+_clientName);
85
86 // loop until we decide to shutdown (run=false)
87 while(run) {
88 try {
89 String cmd = _socketIn.readLine();
90 // make a decision about what to do
91 if(cmd.equals("STARTCONFIG")) {
92 // get the configuration for this client
93 Configuration myConfig = _configManager.getConfiguration("Client."+_clientName);
94 _socketOut.println("OK");
95 _socketOut.flush();
96 // get properties
97 cmd = _socketIn.readLine();
98 // provide all the requested properties
99 while(!cmd.equals("ENDCONFIG")) {
100 // client is restricted to this properties
101 if(cmd.startsWith("Client.") || cmd.startsWith("Host.")) {
102 try {
103 String returnedProperty = myConfig.getProperty(cmd);
104 _socketOut.println(returnedProperty);
105 _socketOut.flush();
106 }
107 catch (org.omg.CORBA.MARSHAL e) {
108 _socketOut.println("ERROR");
109 _socketOut.flush();
110 }
111 }
112 else {
113 _socketOut.println("ERROR");
114 _socketOut.flush();
115 }
116 cmd = _socketIn.readLine();
117 }
118 _socketOut.println("OK");
119 _socketOut.flush();
120 _logger.write(toString(), Logger.SYSMSG, "Client has been configured");
121
122 }
123 else if(cmd.equals("STARTDATA")) {
124 // if we don't have a DataHandler, set one up
125 if(_dataHandler == null) {
126 // create a serversocket
127 ServerSocket ss = new ServerSocket(0);
128 // get the port
129 int port = ss.getLocalPort();
130 // tell the client the port
131 _socketOut.println(port);
132 _socketOut.flush();
133 // wait for the client to connect
134 Socket s = ss.accept();
135 // when we get the Socket back, give it to the data thread
136 TCPDataHandler dh = new TCPDataHandler(s);
137 // register the DataHandler's queue, giving the host list
138 _packetSorter.register(dh.getQueue(), _hostList);
139 // start up the DataHandler
140 dh.start();
141 // Hold a reference to the DataHandler, so we can stop it later
142 _dataHandler = dh;
143 _socketOut.println("OK");
144 _socketOut.flush();
145 _logger.write(toString(), Logger.SYSMSG, "Data stream started at Clients Request on port: "+port);
146 }
147 else {
148 _socketOut.println("ERROR");
149 _socketOut.flush();
150 }
151 }
152 else if(cmd.equals("STOPDATA")) {
153 // if we have a DataHandler, shut it down
154 if(_dataHandler != null) {
155 // Deregister the DataHandler, giving the host list
156 _packetSorter.deregister(_dataHandler.getQueue(), _hostList);
157 // Shut down the data handler
158 _dataHandler.shutdown();
159 // Destroy our reference, leaving it for the GC
160 _dataHandler = null;
161 _socketOut.println("OK");
162 _socketOut.flush();
163 _logger.write(toString(), Logger.SYSMSG, "Data stream stopped at Clients Request");
164 }
165 else {
166 _socketOut.println("ERROR");
167 _socketOut.flush();
168 }
169 }
170 else if(cmd.equals("SETHOSTLIST")) {
171 // we can only set the host list when
172 // the DataHandler is not connected
173 if(_dataHandler == null) {
174 _socketOut.println("OK");
175 _socketOut.flush();
176 // read and set the host list
177 cmd = _socketIn.readLine();
178 _hostList = cmd;
179 _socketOut.println("OK");
180 _socketOut.flush();
181 }
182 else {
183 _socketOut.println("ERROR");
184 _socketOut.flush();
185 }
186 }
187 else if(cmd.equals("DISCONNECT")) {
188 // we going to disconnect, so lets stop this loop
189 run=false;
190 // if there is a DataHandler, we'd best shut it down
191 if(_dataHandler != null) {
192 // Deregister the DataHandler, giving the host list
193 _packetSorter.deregister(_dataHandler.getQueue(), _hostList);
194 // Shut down the data handler
195 _dataHandler.shutdown();
196 // Destroy our reference, leaving it for the GC
197 _dataHandler = null;
198 _socketOut.println("OK");
199 _socketOut.flush();
200 _logger.write(toString(), Logger.SYSMSG, "Data stream stopped at Clients Request");
201 }
202 _socketOut.println("OK");
203 _socketOut.flush();
204 // close the reader, writer and Socket
205 _socketIn.close();
206 _socketOut.close();
207 _socket.close();
208 _logger.write(toString(), Logger.SYSMSG, "Closing at Clients Request");
209 }
210 else {
211 _socketOut.println("ERROR");
212 _socketOut.flush();
213 }
214 }
215 catch(IOException e) {
216 // if we get an exception, the client has probably left, so we stop
217 run=false;
218 _logger.write(toString(), Logger.FATAL, "Fatal communication error, shutdown pending");
219 }
220 }
221 _logger.write(toString(), Logger.SYSMSG, "Shutting down Control Handler, client has gone.");
222 }
223
224 /**
225 * Overrides the {@link java.lang.Object#toString() Object.toString()}
226 * method to provide clean logging (every class should have this).
227 *
228 * This uses the uk.ac.ukc.iscream.util.NameFormat class
229 * to format the toString()
230 *
231 * @return the name of this class and its CVS revision
232 */
233 public String toString() {
234 return FormatName.getName(
235 _name,
236 getClass().getName(),
237 REVISION);
238 }
239
240 //---PRIVATE METHODS---
241
242 //---ACCESSOR/MUTATOR METHODS---
243
244 //---ATTRIBUTES---
245
246 /**
247 * This is the friendly identifier of the
248 * component this class is running in.
249 * eg, a Filter may be called "filter1",
250 * If this class does not have an owning
251 * component, a name from the configuration
252 * can be placed here. This name could also
253 * be changed to null for utility classes.
254 */
255 private String _name = ClientInterfaceMain.NAME;
256
257 /**
258 * This holds a reference to the
259 * system logger that is being used.
260 */
261 private Logger _logger = ReferenceManager.getInstance().getLogger();
262
263 /**
264 * A reference to the Configuration Manager the system is using
265 */
266 private ConfigurationManager _configManager = ReferenceManager.getInstance().getCM();
267
268 /**
269 * The socket we are talking on
270 */
271 private Socket _socket;
272
273 /**
274 * A hook to the inbound data from the socket
275 */
276 private BufferedReader _socketIn;
277
278 /**
279 * A hook to the outbound stream for the socket
280 */
281 private PrintWriter _socketOut;
282
283 /**
284 * A reference to the PacketSorter.
285 */
286 private PacketSorter _packetSorter;
287
288 /**
289 * A reference to the DataHandler, if there is one
290 */
291 private TCPDataHandler _dataHandler;
292
293 /**
294 * The name of the Client we're connected to
295 */
296 private String _clientName;
297
298 /**
299 * The host list the Client has requested
300 */
301 private String _hostList;
302
303 //---STATIC ATTRIBUTES---
304
305 }