1 |
import uk.ac.ukc.iscream.util.*; |
2 |
import java.io.*; |
3 |
import java.net.*; |
4 |
import javax.swing.JOptionPane; |
5 |
|
6 |
public class ConnectionHandler extends Thread { |
7 |
|
8 |
public final String PROTOCOL_VERSION = "PROTOCOL 1.0"; |
9 |
|
10 |
public static final int DONOTHING = 0; |
11 |
public static final int CONNECT = 1; |
12 |
public static final int STARTDATA = 2; |
13 |
public static final int STOPDATA = 3; |
14 |
public static final int DISCONNECT = 4; |
15 |
public static final int QUIT = 5; |
16 |
|
17 |
public ConnectionHandler(DataPanel data, Queue actionQueue) { |
18 |
_data = data; |
19 |
_actionQueue = actionQueue; |
20 |
_myQueue = _actionQueue.getQueue(); |
21 |
} |
22 |
|
23 |
public void run() { |
24 |
|
25 |
while(true) { |
26 |
// we wait for a call... |
27 |
int action = 0; |
28 |
try { |
29 |
action = ((Integer) _actionQueue.get(_myQueue)).intValue(); |
30 |
} catch (InvalidQueueException e) { |
31 |
// we 're never going to get this... |
32 |
} |
33 |
|
34 |
// examine our action... |
35 |
// if it was to connect...then we connect... |
36 |
switch(action) { |
37 |
case CONNECT: |
38 |
|
39 |
Object serverQuestion = null; |
40 |
serverQuestion = JOptionPane.showInputDialog(null, "Please enter the name of a server running the I-Scream client interface:", "I-Scream Server", JOptionPane.INFORMATION_MESSAGE); |
41 |
if (serverQuestion instanceof String) { |
42 |
_server = (String) serverQuestion; |
43 |
SwingClient.setStatus("Connecting to - " + _server); |
44 |
try { |
45 |
_controlLink = new Socket(_server, _port); |
46 |
_inBound = new BufferedReader(new InputStreamReader(_controlLink.getInputStream())); |
47 |
_outBound = new PrintWriter(_controlLink.getOutputStream()); |
48 |
SwingClient.setStatus("Connection Established - " + _server); |
49 |
String response; |
50 |
response = _inBound.readLine(); |
51 |
if (!response.equals(PROTOCOL_VERSION)) { |
52 |
throw new IOException("invalid protocol version"); |
53 |
} |
54 |
SwingClient.addMessage("Handshake Success - " + PROTOCOL_VERSION); |
55 |
|
56 |
// send the name - get from somewhere eventually |
57 |
_outBound.println(_clientName); |
58 |
_outBound.flush(); |
59 |
response = _inBound.readLine(); |
60 |
if (!response.equals("OK")) { |
61 |
throw new IOException("client name rejected - " + response); |
62 |
} |
63 |
SwingClient.addMessage("Control Link Established"); |
64 |
|
65 |
} catch (IOException e) { |
66 |
SwingClient.addMessage("Control Link Error: " + e); |
67 |
SwingClient.setStatus("Disconnected"); |
68 |
} |
69 |
} |
70 |
break; |
71 |
case STARTDATA: |
72 |
SwingClient.addMessage("Attempting to open Data Channel"); |
73 |
try { |
74 |
String response; |
75 |
_outBound.println("STARTDATA"); |
76 |
_outBound.flush(); |
77 |
response = _inBound.readLine(); |
78 |
|
79 |
// TEMPORARY FIREWALL FIX |
80 |
// allows user to map an ssh pipe... |
81 |
JOptionPane.showMessageDialog(null, "WARNING: about to connect to a port you may not have available!\nPlease ensure you have port \"" + response + "\" of your I-Scream server mapped to " + _server, "FIREWALL WARNING!", JOptionPane.INFORMATION_MESSAGE); |
82 |
|
83 |
try { |
84 |
_dataLink = new Socket(_server, Integer.parseInt(response)); |
85 |
} catch (NumberFormatException e) { |
86 |
throw new IOException("error, invalid data port suggested by server - " + response); |
87 |
} |
88 |
response = _inBound.readLine(); |
89 |
if (!response.equals("OK")) { |
90 |
throw new IOException("server reported error establishing data channel - " + response); |
91 |
} |
92 |
_dataInBound = new BufferedReader(new InputStreamReader(_dataLink.getInputStream())); |
93 |
_dataOutBound = new PrintWriter(_dataLink.getOutputStream()); |
94 |
SwingClient.addMessage("Data Link connection established"); |
95 |
SwingClient.addMessage("Starting data reader"); |
96 |
|
97 |
// here we will do some connect stuff. |
98 |
Queue theQueue = new Queue(); |
99 |
_dataReader = new DataReader(_dataInBound, theQueue); |
100 |
_data.setQueue(theQueue); |
101 |
new Thread(_data).start(); |
102 |
_dataReader.start(); |
103 |
// finished for us.... |
104 |
} catch (IOException e) { |
105 |
SwingClient.addMessage("Data Link Error: " + e); |
106 |
} |
107 |
break; |
108 |
case STOPDATA: |
109 |
SwingClient.addMessage("Attempting to close Data Channel"); |
110 |
try { |
111 |
String response; |
112 |
_outBound.println("STOPDATA"); |
113 |
_outBound.flush(); |
114 |
response = _inBound.readLine(); |
115 |
if (!response.equals("OK")) { |
116 |
throw new IOException("server didn't OK request to stop data channel"); |
117 |
} |
118 |
// kill the data reader - we should wait |
119 |
// for it to die nicely...but we won't yet...we'll kill the socket! ;-p |
120 |
_dataReader.setRunning(false); |
121 |
_dataInBound.close(); |
122 |
_dataOutBound.close(); |
123 |
_dataLink.close(); |
124 |
// get rid of the socket |
125 |
_dataLink = null; |
126 |
SwingClient.addMessage("Data Channel closed"); |
127 |
} catch (IOException e) { |
128 |
SwingClient.addMessage("Data Link Error: " + e); |
129 |
} |
130 |
break; |
131 |
case DISCONNECT: |
132 |
SwingClient.addMessage("Attempting to close Control Channel"); |
133 |
try { |
134 |
if (_dataLink != null) { |
135 |
// we want to tell ourselves to stop it |
136 |
_actionQueue.add(new Integer(STOPDATA)); |
137 |
_actionQueue.add(new Integer(DISCONNECT)); |
138 |
throw new IOException("Warning - Data Channel not closed - attempting to close it!"); |
139 |
} |
140 |
String response; |
141 |
_outBound.println("DISCONNECT"); |
142 |
_outBound.flush(); |
143 |
response = _inBound.readLine(); |
144 |
if (!response.equals("OK")) { |
145 |
throw new IOException("server didn't OK request to stop control channel"); |
146 |
} |
147 |
// then lets go! |
148 |
SwingClient.setStatus("Disconnecting - " + _server); |
149 |
_inBound.close(); |
150 |
_outBound.close(); |
151 |
_controlLink.close(); |
152 |
// for good measure |
153 |
_controlLink = null; |
154 |
SwingClient.setStatus("Disconnected"); |
155 |
} catch (IOException e) { |
156 |
SwingClient.addMessage("Control Link Error: " + e); |
157 |
} |
158 |
break; |
159 |
case QUIT: |
160 |
SwingClient.addMessage("Exiting..."); |
161 |
// stop data and control if data up |
162 |
if (_dataLink != null) { |
163 |
_actionQueue.add(new Integer(STOPDATA)); |
164 |
_actionQueue.add(new Integer(DISCONNECT)); |
165 |
_actionQueue.add(new Integer(QUIT)); |
166 |
} |
167 |
// stop control |
168 |
if (_controlLink != null) { |
169 |
_actionQueue.add(new Integer(DISCONNECT)); |
170 |
_actionQueue.add(new Integer(QUIT)); |
171 |
} |
172 |
SwingClient.addMessage("Finished."); |
173 |
// go! |
174 |
System.exit(0); |
175 |
break; |
176 |
} |
177 |
} |
178 |
} |
179 |
|
180 |
|
181 |
SwingClient SwingClient; |
182 |
DataPanel _data; |
183 |
Queue _actionQueue; |
184 |
int _myQueue; |
185 |
String _server; |
186 |
int _port = SwingClient.PORT; |
187 |
Socket _controlLink; |
188 |
Socket _dataLink; |
189 |
BufferedReader _inBound; |
190 |
PrintWriter _outBound; |
191 |
BufferedReader _dataInBound; |
192 |
PrintWriter _dataOutBound; |
193 |
DataReader _dataReader; |
194 |
String _clientName = "CadburyFlakeClient"; |
195 |
} |