source: trunk/src/org/expeditee/network/FrameShare.java@ 649

Last change on this file since 649 was 649, checked in by davidb, 11 years ago

Code added so command-line version of FrameShare starts the thread for the server(s)

File size: 9.7 KB
Line 
1package org.expeditee.network;
2
3import java.io.BufferedReader;
4import java.io.IOException;
5import java.io.StringReader;
6import java.io.StringWriter;
7import java.net.DatagramPacket;
8import java.net.DatagramSocket;
9import java.net.InetAddress;
10import java.net.SocketException;
11import java.net.UnknownHostException;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.LinkedList;
15import java.util.Map;
16
17import org.expeditee.gui.AttributeValuePair;
18import org.expeditee.gui.Frame;
19import org.expeditee.gui.FrameIO;
20import org.expeditee.gui.MessageBay;
21import org.expeditee.io.ExpReader;
22import org.expeditee.io.ExpWriter;
23import org.expeditee.io.FrameReader;
24import org.expeditee.io.FrameWriter;
25import org.expeditee.items.Text;
26
27public class FrameShare {
28
29 public static boolean disableNetworking = false;
30
31 private static final int SOCKET_TIMEOUT = 1000;
32
33 private static Collection<DefaultServer> _servers = new LinkedList<DefaultServer>();
34
35 private static FrameShare _theSession;
36
37 private Map<String, Peer> _peers;
38
39 private int _port = Peer.DEFAULT_PORT;
40
41
42 private void startServers() throws IOException
43 {
44 System.err.println("Starting Expeditee Server on port " + _port);
45 _servers.add(new FrameServer(_port));
46 _servers.add(new FrameSaver(_port));
47 _servers.add(new MessageReciever(_port));
48 _servers.add(new InfServer(_port));
49 _servers.add(new InfUpdate(_port));
50
51 }
52
53 private FrameShare() {
54 _peers = new HashMap<String, Peer>();
55 }
56
57 private FrameShare(int port) {
58 this();
59 _port = port;
60
61 try {
62 startServers();
63
64 } catch (Exception e) {
65 e.printStackTrace();
66 System.err.println("Could not start servers [port: "
67 + port + "]");
68 }
69
70 try {
71 for (DefaultServer server : _servers) {
72 server.start();
73 }
74 } catch (Exception e) {
75 System.err.println("Error in server startup");
76 }
77 }
78
79
80 private FrameShare(Frame settingsFrame)
81 {
82 this();
83
84 // Set the settings
85 for (Text item : settingsFrame.getBodyTextItems(false)) {
86
87 AttributeValuePair avp = new AttributeValuePair(item.getText());
88 if (avp.isAnnotation())
89 continue;
90
91 String attribute = avp.getAttributeOrValue().toLowerCase();
92
93 if (attribute.equals("server")) {
94 try {
95 if (avp.hasPair()) {
96 _port = avp.getIntegerValue();
97 }
98 MessageBay.displayMessage("Starting Expeditee Server on port: " + _port);
99
100 startServers();
101 } catch (Exception e) {
102 e.printStackTrace();
103 MessageBay.errorMessage("Could not start servers ["
104 + avp.toString() + "]");
105 }
106 continue;
107 }
108
109 if (!avp.hasPair())
110 continue;
111
112 try {
113 Peer peer = new Peer(avp);
114 _peers.put(attribute, peer);
115 } catch (UnknownHostException e) {
116 MessageBay.errorMessage("Could not locate peer ["
117 + avp.toString() + "]");
118 }
119 }
120
121 try {
122 for (DefaultServer server : _servers) {
123 server.start();
124 }
125 } catch (Exception e) {
126 MessageBay.errorMessage("Error in PeerToPeer setup");
127 }
128 }
129
130 public void finalise() {
131 System.err.println("Closing servers");
132
133 for (DefaultServer server : _servers)
134 server.close();
135 }
136
137 public static FrameShare getInstance() {
138 return _theSession;
139 }
140
141 /**
142 * TODO check each peer on a different thread.
143 *
144 * @param frameName
145 * @return
146 */
147 public Frame loadFrame(String frameName, String peerName) {
148 String result = null;
149
150 try {
151 // get a datagram socket
152 DatagramSocket socket = new DatagramSocket();
153 socket.setSoTimeout(SOCKET_TIMEOUT * 2);
154 if (peerName == null) {
155 for (Peer peer : _peers.values()) {
156 try {
157 result = getFrameContents(frameName, socket, peer);
158 if(result == null || result.length() == 0) {
159 continue;
160 }
161 peerName = peer.getName();
162 break;
163 } catch (Exception e) {
164 e.printStackTrace();
165 }
166 }
167 } else {
168 try {
169 Peer peer = _peers.get(peerName.toLowerCase());
170 if (peer != null) {
171 result = getFrameContents(frameName, socket, peer);
172 }
173 } catch (Exception e) {
174 e.printStackTrace();
175 }
176 }
177 socket.close();
178 } catch (Exception e) {
179 e.printStackTrace();
180 }
181
182 if (result == null || result.length() == 0)
183 return null;
184
185 // Now read the frame from the file contents
186 FrameReader reader = new ExpReader(frameName);
187 Frame frame = null;
188 try {
189 frame = reader.readFrame(new BufferedReader(
190 new StringReader(result)));
191 // Set the path for the frame to indicate it is NOT a local frame
192 // This allows the frame to be saved in the correct location
193 frame.setLocal(false);
194 frame.setPath(peerName);
195 } catch (IOException e) {
196 e.printStackTrace();
197 }
198
199 if (frame == null) {
200 MessageBay.errorMessage("Error: " + frameName
201 + " could not be successfully loaded.");
202 return null;
203 }
204
205 return frame;
206 }
207
208 /**
209 * @param frameName
210 * @param socket
211 * @param peer
212 * @return
213 * @throws IOException
214 */
215 private String getFrameContents(String frameName, DatagramSocket socket, Peer peer) throws IOException {
216 byte[] nameBuf = frameName.getBytes();
217 byte[] buf = new byte[FrameServer.MAX_PACKET_LENGTH];
218 // send request for a frame
219 DatagramPacket packet = new DatagramPacket(nameBuf,
220 nameBuf.length, peer.getAddress(), peer
221 .getPort());
222 socket.send(packet);
223
224 // get response
225 packet = new DatagramPacket(buf, buf.length);
226 socket.receive(packet);
227
228 // store frame contents
229 return new String(packet.getData(), 0, packet
230 .getLength());
231 }
232
233 public boolean sendMessage(String message, String peerName) {
234 Peer peer = _peers.get(peerName.toLowerCase());
235
236 if (peer == null) {
237 return false;
238 }
239
240 try {
241 // get a datagram socket
242 DatagramSocket socket = new DatagramSocket(_port - 1);
243 socket.setSoTimeout(SOCKET_TIMEOUT);
244
245 // message = peerName + " says " + message;
246 byte[] contentsBuf = message.getBytes();
247
248 try {
249 // send save request
250 DatagramPacket packet = new DatagramPacket(contentsBuf,
251 contentsBuf.length, peer.getAddress(), peer.getPort()
252 + MessageReciever.OFFSET);
253 socket.send(packet);
254 } catch (Exception e) {
255 e.printStackTrace();
256 }
257 socket.close();
258
259 } catch (IOException e) {
260 e.printStackTrace();
261 }
262 return true;
263 }
264
265 public String saveFrame(Frame toSave) {
266
267 FrameIO.setSavedProperties(toSave);
268
269 Peer peer = _peers.get(toSave.getPath().toLowerCase());
270 String fileContents = "";
271 // Now read the frame from the file contents
272 FrameWriter writer = new ExpWriter();
273 try {
274 // String tempName = new Date().toString() + ".exp";
275 // writer.setOutputLocation(tempName);
276 // Write out the file to a StringBuffer
277 StringWriter sw = new StringWriter();
278 // First write out the name of the frame
279 sw.write(toSave.getName() + "\n");
280 // Then the version
281 sw.write(toSave.getVersion() + "\n");
282 // Write out the rest of the frame
283 writer.writeFrame(toSave, sw);
284 // Now send the packet
285 fileContents = sw.getBuffer().toString();
286 byte[] contentsBuf = fileContents.getBytes();
287
288 // get a datagram socket
289 DatagramSocket socket = new DatagramSocket(_port - 2);
290 socket.setSoTimeout(SOCKET_TIMEOUT);
291
292 try {
293 // send save request
294 DatagramPacket packet = new DatagramPacket(contentsBuf,
295 contentsBuf.length, peer.getAddress(), peer.getPort()
296 + FrameSaver.OFFSET);
297 socket.send(packet);
298 } catch (Exception e) {
299 e.printStackTrace();
300 }
301 socket.close();
302
303 } catch (IOException e) {
304 e.printStackTrace();
305 }
306 toSave.setSaved();
307 return fileContents;
308 }
309
310 public String getPeerName(int port, InetAddress address) {
311 for (Peer p : _peers.values()) {
312 if (p.getPort() == port && p.getAddress().equals(address))
313 return p.getName();
314 }
315 return null;
316 }
317
318 public int getInfNumber(String peerName, String frameset, boolean update)
319 throws IOException {
320 int result = -1;
321 // get a datagram socket
322 DatagramSocket socket = null;
323 try {
324 socket = new DatagramSocket(_port - 3);
325 socket.setSoTimeout(SOCKET_TIMEOUT);
326
327 byte[] contentsBuf = frameset.getBytes();
328 Peer peer = _peers.get(peerName.toLowerCase());
329 try {
330 // send inf request
331 DatagramPacket packet = new DatagramPacket(
332 contentsBuf,
333 contentsBuf.length,
334 peer.getAddress(),
335 peer.getPort()
336 + (update ? InfUpdate.OFFSET : InfServer.OFFSET));
337 socket.send(packet);
338
339 byte[] buf = new byte[100];
340 // get response
341 packet = new DatagramPacket(buf, buf.length);
342 socket.receive(packet);
343
344 // store frame contents
345 result = Integer.parseInt(new String(packet.getData(), 0,
346 packet.getLength()));
347 peerName = peer.getName();
348
349 } catch (Exception e) {
350 e.printStackTrace();
351 }
352 socket.close();
353 } catch (SocketException e1) {
354 e1.printStackTrace();
355 }
356
357 return result;
358 }
359
360 public static void init(Frame settingsFrame) {
361 if (disableNetworking || settingsFrame == null)
362 return;
363
364 if (_theSession == null)
365 _theSession = new FrameShare(settingsFrame);
366 }
367
368 public static void init(int port) {
369
370 if (_theSession == null) {
371 _theSession = new FrameShare(port);
372 }
373 }
374
375
376 /**
377 * Start a server running on the port number supplied on the command line
378 *
379 * @param args
380 */
381 public static void main(String[] args) {
382
383 if (args.length != 1) {
384
385 // Work out the 'program name' (i.e. this class), but done in a general
386 // way in case class name is changed at a later date
387 StackTraceElement[] stack = Thread.currentThread ().getStackTrace ();
388 StackTraceElement main = stack[stack.length - 1];
389 String mainClass = main.getClassName ();
390
391 System.err.println("Usage: java " + mainClass + " port-number");
392 System.exit(1);
393 }
394
395 String port_str = args[0];
396
397 try {
398 int port = Integer.parseInt(port_str);
399
400 init(port);
401 }
402 catch (Exception e) {
403 e.printStackTrace();
404 System.exit(2);
405 }
406
407 }
408
409}
Note: See TracBrowser for help on using the repository browser.