picrate 0.9.0-java → 1.0.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
2
 
3
- /*
3
+ /*
4
4
  Server - basic network server implementation
5
5
  Part of the Processing project - http://processing.org
6
6
 
@@ -21,365 +21,368 @@
21
21
  Public License along with this library; if not, write to the
22
22
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
23
23
  Boston, MA 02111-1307 USA
24
- */
24
+ */
25
+
25
26
  package processing.net;
26
27
 
27
- import java.io.IOException;
28
- import java.lang.reflect.InvocationTargetException;
29
- import java.lang.reflect.Method;
30
- import java.net.InetAddress;
31
- import java.net.ServerSocket;
32
- import java.net.Socket;
33
- import java.net.SocketException;
34
- import java.net.UnknownHostException;
35
- import processing.core.PApplet;
28
+ import processing.core.*;
29
+
30
+ import java.io.*;
31
+ import java.lang.reflect.*;
32
+ import java.net.*;
33
+
36
34
 
37
35
  /**
38
36
  * ( begin auto-generated from Server.xml )
39
- *
40
- * A server sends and receives data to and from its associated clients (other
41
- * programs connected to it). When a server is started, it begins listening for
42
- * connections on the port specified by the <b>port</b>
43
- * parameter. Computers have many ports for transferring data and some are
44
- * commonly used so be sure to not select one of these. For example, web servers
45
- * usually use port 80 and POP mail uses port 110.
46
- *
37
+ *
38
+ * A server sends and receives data to and from its associated clients
39
+ * (other programs connected to it). When a server is started, it begins
40
+ * listening for connections on the port specified by the <b>port</b>
41
+ * parameter. Computers have many ports for transferring data and some are
42
+ * commonly used so be sure to not select one of these. For example, web
43
+ * servers usually use port 80 and POP mail uses port 110.
44
+ *
47
45
  * ( end auto-generated )
48
- *
49
46
  * @webref net
50
47
  * @usage application
51
- * @brief The server class is used to create server objects which send and
52
- * receives data to and from its associated clients (other programs connected to
53
- * it).
54
- * @instanceName server any variable of type Server
48
+ * @brief The server class is used to create server objects which send and receives data to and from its associated clients (other programs connected to it).
49
+ * @instanceName server any variable of type Server
55
50
  */
56
51
  public class Server implements Runnable {
57
-
58
- PApplet parent;
59
- Method serverEventMethod;
60
-
61
- volatile Thread thread;
62
- ServerSocket server;
63
- int port;
64
-
65
- protected final Object clientsLock = new Object[0];
66
- /**
67
- * Number of clients currently connected.
68
- */
69
- public int clientCount;
70
- /**
71
- * Array of client objects, useful length is determined by clientCount.
72
- */
73
- public Client[] clients;
74
-
75
- /**
76
- * @param parent typically use "this"
77
- * @param port port used to transfer data
78
- */
79
- public Server(PApplet parent, int port) {
80
- this(parent, port, null);
52
+ PApplet parent;
53
+ Method serverEventMethod;
54
+
55
+ volatile Thread thread;
56
+ ServerSocket server;
57
+ int port;
58
+
59
+ protected final Object clientsLock = new Object[0];
60
+ /** Number of clients currently connected. */
61
+ public int clientCount;
62
+ /** Array of client objects, useful length is determined by clientCount. */
63
+ public Client[] clients;
64
+
65
+
66
+ /**
67
+ * @param parent typically use "this"
68
+ * @param port port used to transfer data
69
+ */
70
+ public Server(PApplet parent, int port) {
71
+ this(parent, port, null);
72
+ }
73
+
74
+
75
+ /**
76
+ * @param parent typically use "this"
77
+ * @param port port used to transfer data
78
+ * @param host when multiple NICs are in use, the ip (or name) to bind from
79
+ */
80
+ public Server(PApplet parent, int port, String host) {
81
+ this.parent = parent;
82
+ this.port = port;
83
+
84
+ try {
85
+ if (host == null) {
86
+ server = new ServerSocket(this.port);
87
+ } else {
88
+ server = new ServerSocket(this.port, 10, InetAddress.getByName(host));
89
+ }
90
+ //clients = new Vector();
91
+ clients = new Client[10];
92
+
93
+ thread = new Thread(this);
94
+ thread.start();
95
+
96
+ parent.registerMethod("dispose", this);
97
+
98
+ // reflection to check whether host applet has a call for
99
+ // public void serverEvent(Server s, Client c);
100
+ // which is called when a new guy connects
101
+ try {
102
+ serverEventMethod =
103
+ parent.getClass().getMethod("serverEvent", Server.class, Client.class);
104
+ } catch (Exception e) {
105
+ // no such method, or an error.. which is fine, just ignore
106
+ }
107
+
108
+ } catch (IOException e) {
109
+ //e.printStackTrace();
110
+ thread = null;
111
+ throw new RuntimeException(e);
112
+ //errorMessage("<init>", e);
81
113
  }
82
-
83
- /**
84
- * @param parent typically use "this"
85
- * @param port port used to transfer data
86
- * @param host when multiple NICs are in use, the ip (or name) to bind from
87
- */
88
- public Server(PApplet parent, int port, String host) {
89
- this.parent = parent;
90
- this.port = port;
91
-
92
- try {
93
- if (host == null) {
94
- server = new ServerSocket(this.port);
95
- } else {
96
- server = new ServerSocket(this.port, 10, InetAddress.getByName(host));
97
- }
98
- //clients = new Vector();
99
- clients = new Client[10];
100
-
101
- thread = new Thread(this);
102
- thread.start();
103
-
104
- parent.registerMethod("dispose", this);
105
-
106
- // reflection to check whether host applet has a call for
107
- // public void serverEvent(Server s, Client c);
108
- // which is called when a new guy connects
109
- try {
110
- serverEventMethod
111
- = parent.getClass().getMethod("serverEvent", Server.class, Client.class);
112
- } catch (NoSuchMethodException | SecurityException e) {
113
- // no such method, or an error.. which is fine, just ignore
114
- }
115
-
116
- } catch (IOException e) {
117
- //e.printStackTrace();
118
- thread = null;
119
- throw new RuntimeException(e);
120
- //errorMessage("<init>", e);
121
- }
114
+ }
115
+
116
+
117
+ /**
118
+ * ( begin auto-generated from Server_disconnect.xml )
119
+ *
120
+ * Disconnect a particular client.
121
+ *
122
+ * ( end auto-generated )
123
+ * @brief Disconnect a particular client.
124
+ * @webref server:server
125
+ * @param client the client to disconnect
126
+ */
127
+ public void disconnect(Client client) {
128
+ client.stop();
129
+ synchronized (clientsLock) {
130
+ int index = clientIndex(client);
131
+ if (index != -1) {
132
+ removeIndex(index);
133
+ }
122
134
  }
123
-
124
- /**
125
- * ( begin auto-generated from Server_disconnect.xml )
126
- *
127
- * Disconnect a particular client.
128
- *
129
- * ( end auto-generated )
130
- *
131
- * @brief Disconnect a particular client.
132
- * @webref server:server
133
- * @param client the client to disconnect
134
- */
135
- public void disconnect(Client client) {
136
- client.stop();
137
- synchronized (clientsLock) {
138
- int index = clientIndex(client);
139
- if (index != -1) {
140
- removeIndex(index);
141
- }
142
- }
143
- }
144
-
145
- protected void removeIndex(int index) {
146
- synchronized (clientsLock) {
147
- clientCount--;
148
- // shift down the remaining clients
149
- for (int i = index; i < clientCount; i++) {
150
- clients[i] = clients[i + 1];
151
- }
152
- // mark last empty var for garbage collection
153
- clients[clientCount] = null;
154
- }
135
+ }
136
+
137
+
138
+ protected void removeIndex(int index) {
139
+ synchronized (clientsLock) {
140
+ clientCount--;
141
+ // shift down the remaining clients
142
+ for (int i = index; i < clientCount; i++) {
143
+ clients[i] = clients[i + 1];
144
+ }
145
+ // mark last empty var for garbage collection
146
+ clients[clientCount] = null;
155
147
  }
156
-
157
- protected void disconnectAll() {
158
- synchronized (clientsLock) {
159
- for (int i = 0; i < clientCount; i++) {
160
- try {
161
- clients[i].stop();
162
- } catch (Exception e) {
163
- // ignore
164
- }
165
- clients[i] = null;
166
- }
167
- clientCount = 0;
148
+ }
149
+
150
+
151
+ protected void disconnectAll() {
152
+ synchronized (clientsLock) {
153
+ for (int i = 0; i < clientCount; i++) {
154
+ try {
155
+ clients[i].stop();
156
+ } catch (Exception e) {
157
+ // ignore
168
158
  }
159
+ clients[i] = null;
160
+ }
161
+ clientCount = 0;
169
162
  }
170
-
171
- protected void addClient(Client client) {
172
- synchronized (clientsLock) {
173
- if (clientCount == clients.length) {
174
- clients = (Client[]) PApplet.expand(clients);
175
- }
176
- clients[clientCount++] = client;
177
- }
163
+ }
164
+
165
+
166
+ protected void addClient(Client client) {
167
+ synchronized (clientsLock) {
168
+ if (clientCount == clients.length) {
169
+ clients = (Client[]) PApplet.expand(clients);
170
+ }
171
+ clients[clientCount++] = client;
178
172
  }
179
-
180
- protected int clientIndex(Client client) {
181
- synchronized (clientsLock) {
182
- for (int i = 0; i < clientCount; i++) {
183
- if (clients[i] == client) {
184
- return i;
185
- }
186
- }
187
- return -1;
173
+ }
174
+
175
+
176
+ protected int clientIndex(Client client) {
177
+ synchronized (clientsLock) {
178
+ for (int i = 0; i < clientCount; i++) {
179
+ if (clients[i] == client) {
180
+ return i;
188
181
  }
182
+ }
183
+ return -1;
189
184
  }
190
-
191
- /**
192
- * ( begin auto-generated from Server_active.xml )
193
- *
194
- * Returns true if this server is still active and hasn't run into any
195
- * trouble.( end auto-generated )
196
- *
197
- *
198
- * @return
199
- * @webref server:server
200
- * @brief Return true if this server is still active.
201
- */
202
- public boolean active() {
203
- return thread != null;
185
+ }
186
+
187
+
188
+ /**
189
+ * ( begin auto-generated from Server_active.xml )
190
+ *
191
+ * Returns true if this server is still active and hasn't run
192
+ * into any trouble.
193
+ *
194
+ * ( end auto-generated )
195
+ * @webref server:server
196
+ * @brief Return true if this server is still active.
197
+ */
198
+ public boolean active() {
199
+ return thread != null;
200
+ }
201
+
202
+
203
+ static public String ip() {
204
+ try {
205
+ return InetAddress.getLocalHost().getHostAddress();
206
+ } catch (UnknownHostException e) {
207
+ e.printStackTrace();
208
+ return null;
204
209
  }
205
-
206
- static public String ip() {
207
- try {
208
- return InetAddress.getLocalHost().getHostAddress();
209
- } catch (UnknownHostException e) {
210
- return null;
210
+ }
211
+
212
+
213
+ // the last index used for available. can't just cycle through
214
+ // the clients in order from 0 each time, because if client 0 won't
215
+ // shut up, then the rest of the clients will never be heard from.
216
+ int lastAvailable = -1;
217
+
218
+ /**
219
+ * ( begin auto-generated from Server_available.xml )
220
+ *
221
+ * Returns the next client in line with a new message.
222
+ *
223
+ * ( end auto-generated )
224
+ * @brief Returns the next client in line with a new message.
225
+ * @webref server
226
+ * @usage application
227
+ */
228
+ public Client available() {
229
+ synchronized (clientsLock) {
230
+ int index = lastAvailable + 1;
231
+ if (index >= clientCount) index = 0;
232
+
233
+ for (int i = 0; i < clientCount; i++) {
234
+ int which = (index + i) % clientCount;
235
+ Client client = clients[which];
236
+ //Check for valid client
237
+ if (!client.active()){
238
+ removeIndex(which); //Remove dead client
239
+ i--; //Don't skip the next client
240
+ //If the client has data make sure lastAvailable
241
+ //doesn't end up skipping the next client
242
+ which--;
243
+ //fall through to allow data from dead clients
244
+ //to be retreived.
211
245
  }
212
- }
213
-
214
- // the last index used for available. can't just cycle through
215
- // the clients in order from 0 each time, because if client 0 won't
216
- // shut up, then the rest of the clients will never be heard from.
217
- int lastAvailable = -1;
218
-
219
- /**
220
- * ( begin auto-generated from Server_available.xml )
221
- *
222
- * Returns the next client in line with a new message.( end auto-generated )
223
- *
224
- *
225
- * @return
226
- * @brief Returns the next client in line with a new message.
227
- * @webref server
228
- * @usage application
229
- */
230
- public Client available() {
231
- synchronized (clientsLock) {
232
- int index = lastAvailable + 1;
233
- if (index >= clientCount) {
234
- index = 0;
235
- }
236
-
237
- for (int i = 0; i < clientCount; i++) {
238
- int which = (index + i) % clientCount;
239
- Client client = clients[which];
240
- //Check for valid client
241
- if (!client.active()) {
242
- removeIndex(which); //Remove dead client
243
- i--; //Don't skip the next client
244
- //If the client has data make sure lastAvailable
245
- //doesn't end up skipping the next client
246
- which--;
247
- //fall through to allow data from dead clients
248
- //to be retreived.
249
- }
250
- if (client.available() > 0) {
251
- lastAvailable = which;
252
- return client;
253
- }
254
- }
246
+ if (client.available() > 0) {
247
+ lastAvailable = which;
248
+ return client;
255
249
  }
256
- return null;
250
+ }
257
251
  }
258
-
259
- /**
260
- * ( begin auto-generated from Server_stop.xml )
261
- *
262
- * Disconnects all clients and stops the server.
263
- *
264
- * ( end auto-generated )
265
- * <h3>Advanced</h3>
266
- * Use this to shut down the server if you finish using it while your applet
267
- * is still running. Otherwise, it will be automatically be shut down by the
268
- * host PApplet using dispose(), which is identical.
269
- *
270
- * @brief Disconnects all clients and stops the server.
271
- * @webref server
272
- * @usage application
273
- */
274
- public void stop() {
275
- dispose();
252
+ return null;
253
+ }
254
+
255
+
256
+ /**
257
+ * ( begin auto-generated from Server_stop.xml )
258
+ *
259
+ * Disconnects all clients and stops the server.
260
+ *
261
+ * ( end auto-generated )
262
+ * <h3>Advanced</h3>
263
+ * Use this to shut down the server if you finish using it while your applet
264
+ * is still running. Otherwise, it will be automatically be shut down by the
265
+ * host PApplet using dispose(), which is identical.
266
+ * @brief Disconnects all clients and stops the server.
267
+ * @webref server
268
+ * @usage application
269
+ */
270
+ public void stop() {
271
+ dispose();
272
+ }
273
+
274
+
275
+ /**
276
+ * Disconnect all clients and stop the server: internal use only.
277
+ */
278
+ public void dispose() {
279
+ thread = null;
280
+
281
+ if (clients != null) {
282
+ disconnectAll();
283
+ clientCount = 0;
284
+ clients = null;
276
285
  }
277
286
 
278
- /**
279
- * Disconnect all clients and stop the server: internal use only.
280
- */
281
- public void dispose() {
282
- thread = null;
283
-
284
- if (clients != null) {
285
- disconnectAll();
286
- clientCount = 0;
287
- clients = null;
288
- }
289
-
290
- try {
291
- if (server != null) {
292
- server.close();
293
- server = null;
294
- }
295
- } catch (IOException e) {
296
- }
287
+ try {
288
+ if (server != null) {
289
+ server.close();
290
+ server = null;
291
+ }
292
+ } catch (IOException e) {
293
+ e.printStackTrace();
297
294
  }
295
+ }
296
+
298
297
 
299
- @Override
300
- public void run() {
301
- while (Thread.currentThread() == thread) {
298
+ @Override
299
+ public void run() {
300
+ while (Thread.currentThread() == thread) {
301
+ try {
302
+ Socket socket = server.accept();
303
+ Client client = new Client(parent, socket);
304
+ synchronized (clientsLock) {
305
+ addClient(client);
306
+ if (serverEventMethod != null) {
302
307
  try {
303
- Socket socket = server.accept();
304
- Client client = new Client(parent, socket);
305
- synchronized (clientsLock) {
306
- addClient(client);
307
- if (serverEventMethod != null) {
308
- try {
309
- serverEventMethod.invoke(parent, this, client);
310
- } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
311
- System.err.println("Disabling serverEvent() for port " + port);
312
- Throwable cause = e;
313
- // unwrap the exception if it came from the user code
314
- if (e instanceof InvocationTargetException && e.getCause() != null) {
315
- cause = e.getCause();
316
- }
317
- serverEventMethod = null;
318
- }
319
- }
320
- }
321
- } catch (SocketException e) {
322
- //thrown when server.close() is called and server is waiting on accept
323
- System.err.println("Server SocketException: " + e.getMessage());
324
- thread = null;
325
- } catch (IOException e) {
326
- //errorMessage("run", e);
327
- thread = null;
308
+ serverEventMethod.invoke(parent, this, client);
309
+ } catch (Exception e) {
310
+ System.err.println("Disabling serverEvent() for port " + port);
311
+ Throwable cause = e;
312
+ // unwrap the exception if it came from the user code
313
+ if (e instanceof InvocationTargetException && e.getCause() != null) {
314
+ cause = e.getCause();
315
+ }
316
+ cause.printStackTrace();
317
+ serverEventMethod = null;
328
318
  }
319
+ }
329
320
  }
321
+ } catch (SocketException e) {
322
+ //thrown when server.close() is called and server is waiting on accept
323
+ System.err.println("Server SocketException: " + e.getMessage());
324
+ thread = null;
325
+ } catch (IOException e) {
326
+ //errorMessage("run", e);
327
+ e.printStackTrace();
328
+ thread = null;
329
+ }
330
330
  }
331
-
332
- /**
333
- * ( begin auto-generated from Server_write.xml )
334
- *
335
- * Writes a value to all the connected clients. It sends bytes out from the
336
- * Server object.
337
- *
338
- * ( end auto-generated )
339
- *
340
- * @webref server
341
- * @brief Writes data to all connected clients
342
- * @param data data to write
343
- */
344
- public void write(int data) { // will also cover char
345
- synchronized (clientsLock) {
346
- int index = 0;
347
- while (index < clientCount) {
348
- if (clients[index].active()) {
349
- clients[index].write(data);
350
- index++;
351
- } else {
352
- removeIndex(index);
353
- }
354
- }
331
+ }
332
+
333
+
334
+ /**
335
+ * ( begin auto-generated from Server_write.xml )
336
+ *
337
+ * Writes a value to all the connected clients. It sends bytes out from the
338
+ * Server object.
339
+ *
340
+ * ( end auto-generated )
341
+ * @webref server
342
+ * @brief Writes data to all connected clients
343
+ * @param data data to write
344
+ */
345
+ public void write(int data) { // will also cover char
346
+ synchronized (clientsLock) {
347
+ int index = 0;
348
+ while (index < clientCount) {
349
+ if (clients[index].active()) {
350
+ clients[index].write(data);
351
+ index++;
352
+ } else {
353
+ removeIndex(index);
355
354
  }
355
+ }
356
356
  }
357
-
358
- public void write(byte data[]) {
359
- synchronized (clientsLock) {
360
- int index = 0;
361
- while (index < clientCount) {
362
- if (clients[index].active()) {
363
- clients[index].write(data);
364
- index++;
365
- } else {
366
- removeIndex(index);
367
- }
368
- }
357
+ }
358
+
359
+
360
+ public void write(byte data[]) {
361
+ synchronized (clientsLock) {
362
+ int index = 0;
363
+ while (index < clientCount) {
364
+ if (clients[index].active()) {
365
+ clients[index].write(data);
366
+ index++;
367
+ } else {
368
+ removeIndex(index);
369
369
  }
370
+ }
370
371
  }
371
-
372
- public void write(String data) {
373
- synchronized (clientsLock) {
374
- int index = 0;
375
- while (index < clientCount) {
376
- if (clients[index].active()) {
377
- clients[index].write(data);
378
- index++;
379
- } else {
380
- removeIndex(index);
381
- }
382
- }
372
+ }
373
+
374
+
375
+ public void write(String data) {
376
+ synchronized (clientsLock) {
377
+ int index = 0;
378
+ while (index < clientCount) {
379
+ if (clients[index].active()) {
380
+ clients[index].write(data);
381
+ index++;
382
+ } else {
383
+ removeIndex(index);
383
384
  }
385
+ }
384
386
  }
387
+ }
385
388
  }