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