View Javadoc
1   /*
2    * Created on 2004-12-04
3    *
4    * Klasa odpowiada za odbieranie pakietów z sieci, przekazywanie ich do bufora
5    * odbiorczego i uruchomienie notyfikacji obiektów które obserwują bufor.
6    */
7   
8   package org.sourceforge.jvb3d.Network;
9   
10  import java.net.DatagramSocket;
11  import java.net.DatagramPacket;
12  import java.net.InetSocketAddress;
13  import java.net.SocketException;
14  import java.net.SocketTimeoutException;
15  import java.io.ByteArrayInputStream;
16  import java.io.IOException;
17  import java.io.ObjectInputStream;
18  import java.util.logging.*;
19  
20  /***
21   * @author Łukasz Krzyżak
22   * 
23   * Klasa odpowiada za odbieranie pakietów z sieci, przekazywanie ich do bufora
24   * odbiorczego i uruchomienie notyfikacji obiektów które obserwują bufor.
25   */
26  public class NetworkReceiver extends Thread {
27  	/***
28  	 * socket służący do komunikacji instancji programu z innymi kopiami
29  	 */
30  	public static DatagramSocket listeningSocket = null;
31  
32  	private DatagramPacket recvPacket;
33  
34  	private ReceivedPacketBuffer packetBuffer = null;
35  
36  	private boolean terminate = false;
37  
38  	private ObjectInputStream objectInputStream = null;
39  
40  	private ByteArrayInputStream byteArrayInputStream = null;
41  
42  	private static final int maxPacketSize = 4096;
43  
44  	private static final int socketTimeout = 1000;
45  
46  	private static final Logger fLogger = Logger.getLogger("NetworkReceiver");
47  
48  	/***
49  	 * Wiąże obiekt z podanym portem
50  	 * 
51  	 * @param port
52  	 *            numer portu na którym ma słuchać socket
53  	 * @throws SocketException jeśli wystąpi błąd socketu
54  	 * @throws IOException jeśli wystąpi błąd przesyłania
55  	 */
56  	public NetworkReceiver(int port) throws SocketException, IOException {
57  		if(port == 0) 
58  			listeningSocket = new DatagramSocket();
59  		else
60  			listeningSocket = new DatagramSocket(port);
61  		listeningSocket.setSoTimeout(socketTimeout);
62  
63  		byte[] dataBuffer = new byte[maxPacketSize];
64  
65  		byteArrayInputStream = new ByteArrayInputStream(dataBuffer);
66  		recvPacket = new DatagramPacket(dataBuffer, maxPacketSize);
67  	}
68  
69  	/***
70  	 * ustawia timeout socketu
71  	 * @param timeout czas w ms
72  	 * @throws SocketException jeśli podano błędną wartość 
73  	 */
74  	public void setTimeout(int timeout) throws SocketException {
75  		listeningSocket.setSoTimeout(timeout);
76  	}
77  
78  	/***
79  	 * powoduje zakończenie nasłuchiwania na danym sockecie i zakończenie wątku
80  	 *
81  	 */
82  	public void finish() {
83  		terminate = true;
84  	}
85  
86  	/***
87  	 * zamyka socket i odpina go od portu
88  	 *  
89  	 */
90  	public void terminate() {
91  		listeningSocket.close();
92  	}
93  
94  	/***
95  	 * Wiąże obiekt z buforem
96  	 * 
97  	 * @param buffer
98  	 *            obiekt bufora z którym należy powiązać receivera
99  	 */
100 	public void connectToBuffer(ReceivedPacketBuffer buffer) {
101 		packetBuffer = buffer;
102 	}
103 
104 	/***
105 	 * Uruchamia nasłuchiwanie na sockecie. Jeśli zostanie odebrany pakiet -
106 	 * zostaje przekazany do bufora, a następnie bufor jest informowany o
107 	 * konieczności notyfikacji observerów.
108 	 * 
109 	 * @throws NullPointerException
110 	 *             wyjątek rzucany, jeśli próbujemy wystartować metodę, a nie
111 	 *             powiązaliśmy obiektu z buforem
112 	 *  
113 	 */
114 	public void run() {
115 		if (packetBuffer == null)
116 			throw new NullPointerException();
117 		while (!terminate) {
118 			try {
119 				listeningSocket.receive(recvPacket);
120 				
121 				byteArrayInputStream.reset();
122 				if (objectInputStream == null)
123 					objectInputStream = new ObjectInputStream(
124 							byteArrayInputStream);
125 				else
126 					byteArrayInputStream.skip(4);
127 
128 				Packet receivedPacket = (Packet) objectInputStream.readObject();
129 				receivedPacket.setSourceAddress((InetSocketAddress)recvPacket.getSocketAddress());
130 				packetBuffer.addPacket(receivedPacket);
131 				packetBuffer.notifyObservers();
132 			} catch (SocketTimeoutException e) {
133 				if(!terminate) fLogger.fine(e.toString());
134 			} catch (IOException e) {
135 				throw new NullPointerException(e.toString());
136 			} catch (ClassNotFoundException e) {
137 				throw new NullPointerException(e.toString());
138 			}
139 		}
140 	}
141 }