KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > datashare > client > DataShareConnection


1 /* ----- BEGIN LICENSE BLOCK -----
2  * Version: MPL 1.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code was the Rendezvous client.
15  * The Code is the DataShare server.
16  *
17  * The Initial Developer of the Original Code is
18  * Ball Aerospace & Technologies Corp, Fairborn, Ohio
19  * Portions created by the Initial Developer are Copyright (C) 2001
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s): Charles Wood <cwood@ball.com>
23  *
24  * ----- END LICENSE BLOCK ----- */

25 /* RCS $Id: DataShareConnection.java,v 1.3 2002/01/29 20:55:59 lizellaman Exp $
26  * $Log: DataShareConnection.java,v $
27  * Revision 1.3 2002/01/29 20:55:59 lizellaman
28  * Added LoggingInterface, modified the PropertiesInterface implementation
29  *
30  * Revision 1.2 2002/01/20 23:31:21 lizellaman
31  * add code to handle 'keepalive' packets for if/when DataShare server decides that a connection has been idle too long
32  *
33  * Revision 1.1 2002/01/03 03:21:36 lizellaman
34  * existing file, moved to client package
35  *
36  * Revision 1.1.1.1 2001/10/23 13:43:48 lizellaman
37  * initial sourceforge release
38  *
39  */

40
41 package org.datashare.client;
42
43 import java.net.Socket JavaDoc;
44 import java.net.DatagramSocket JavaDoc;
45 import java.net.MulticastSocket JavaDoc;
46 import java.net.InetAddress JavaDoc;
47 import java.io.ObjectOutputStream JavaDoc;
48 import java.io.ObjectInputStream JavaDoc;
49 import java.io.ByteArrayInputStream JavaDoc;
50 import java.io.ByteArrayOutputStream JavaDoc;
51 import java.io.BufferedInputStream JavaDoc;
52 import java.io.BufferedOutputStream JavaDoc;
53 import java.io.InputStream JavaDoc;
54 import java.io.OutputStream JavaDoc;
55 import java.io.IOException JavaDoc;
56 import java.io.StreamCorruptedException JavaDoc;
57 import java.io.UTFDataFormatException JavaDoc;
58 import java.net.DatagramPacket JavaDoc;
59
60 import org.datashare.objects.DataShareObject;
61 import org.datashare.objects.DataShareConnectionDescriptor;
62 import org.datashare.objects.ChannelDescription;
63 import org.datashare.objects.ActivateConnectionObject;
64 import org.datashare.SessionUtilities;
65
66 /**
67  * This is the client side implementation of our network connection (formerly called channels)
68  * We use this to send data, and it is provided the object that will be given any received data
69  * and the notification if something bad happens to this socket...
70  */

71 public class DataShareConnection implements Runnable JavaDoc
72    {
73    Socket JavaDoc tcpSocket = null;
74    DatagramSocket JavaDoc udpSocket = null;
75    MulticastSocket JavaDoc multicastSocket = null;
76    ObjectOutputStream JavaDoc oos = null;
77    ObjectInputStream JavaDoc ois = null;
78    private boolean running = true; // set to false to stop thread
79
private boolean closeAllCalled = false;
80    public DataShareConnectionDescriptor dscd = null;
81    ClientDataReceiverInterface cdri = null;
82    DatagramPacket JavaDoc sndPacket = null; // used when sending UDP stuff
83
DatagramPacket JavaDoc rcvPacket = null; // used when receiving UDP stuff
84
protected int type;
85    private boolean completed = false;
86    public String JavaDoc keyValue;
87    private int sndBuffSize = -1;
88    private int rcvBuffSize = -1;
89    private byte[] byteArrayInstance = null;
90
91    public DataShareConnection(DataShareConnectionDescriptor dscd1, ClientDataReceiverInterface cdri) throws Exception JavaDoc
92       {
93       type = dscd1.type;
94       dscd = dscd1;
95       this.cdri = cdri;
96
97       switch(type)
98          {
99          case ChannelDescription.TCP:
100             {
101             System.out.println("Creating a TCP DataShareConnection instance for " + dscd.serverIP +":"+dscd.serverPort);
102             try{
103                if(dscd.completelySpecified) // should never get here if we are really on client side, but just in case...
104
tcpSocket = new Socket JavaDoc(dscd.serverIP, dscd.serverPort, dscd.clientIP, dscd.clientPort);
105                else
106                   {
107                   tcpSocket = new Socket JavaDoc(dscd.serverIP, dscd.serverPort);
108                   dscd.clientIP = tcpSocket.getLocalAddress();
109                   dscd.clientPort = tcpSocket.getLocalPort();
110                   dscd.completelySpecified = true;
111                   }
112                oos = new ObjectOutputStream JavaDoc(tcpSocket.getOutputStream());
113                ois = new ObjectInputStream JavaDoc(tcpSocket.getInputStream());
114                Thread JavaDoc me = new Thread JavaDoc(this,"DataShareConnectionFor"+dscd.channelDescription.channelName+"OnServerPort"+dscd.serverPort);
115                me.start();
116                keyValue = "TCP-" + dscd.serverIP.getHostAddress()+":"+dscd.serverPort+"-"+dscd.clientIP.getHostAddress()+":"+dscd.clientPort;
117                while(!completed)
118                   {
119                   //System.out.println("waiting for connection thread to start...");
120
SessionUtilities.delay(100);
121                   }
122                }
123             catch(Exception JavaDoc e)
124                {
125                System.out.println("Problems creating our tcpSocket...");
126                //e.printStackTrace();
127
System.out.println(e);
128                //throw new Exception(e.toString());
129
throw e;
130                }
131             break;
132             }
133          case ChannelDescription.UDP:
134             {
135             System.out.println("Creating a UDP DataShareConnection instance for " + dscd.serverIP +":"+dscd.serverPort);
136             try{
137                udpSocket = new DatagramSocket JavaDoc();
138                udpSocket.setReceiveBufferSize(15000);
139                udpSocket.setSendBufferSize(10000);
140                rcvBuffSize = udpSocket.getReceiveBufferSize();
141                if(SessionUtilities.getVerbose())
142                   System.out.println("UDP socket max receive size is " + rcvBuffSize);
143                sndBuffSize = udpSocket.getSendBufferSize();
144                if(SessionUtilities.getVerbose())
145                   System.out.println("UDP socket max send size is " + sndBuffSize);
146                dscd.clientIP = InetAddress.getLocalHost();
147                //dscd.clientIP = udpSocket.getLocalAddress(); doesn't seem to work
148
dscd.clientPort = udpSocket.getLocalPort();
149                dscd.completelySpecified = true;
150                Thread JavaDoc me = new Thread JavaDoc(this,"DataShareConnectionFor"+dscd.channelDescription.channelName);
151                me.start();
152                keyValue = "UDP-" + dscd.serverIP.getHostAddress()+":"+dscd.serverPort+"-"+dscd.clientIP.getHostAddress()+":"+dscd.clientPort;
153                while(!completed)
154                   {
155                   //System.out.println("waiting for connection thread to start...");
156
SessionUtilities.delay(100);
157                   }
158                }
159             catch(Exception JavaDoc e2)
160                {
161                System.out.println("Problems creating our udpSocket...");
162                e2.printStackTrace();
163                throw new Exception JavaDoc(e2.toString());
164                }
165             break;
166             }
167          case ChannelDescription.MULTICAST:
168             {
169             System.out.println("Creating a Multicast DataShareConnection instance for " + dscd.serverIP +":"+dscd.serverPort);
170             try{
171                multicastSocket = new MulticastSocket JavaDoc(dscd.serverPort); // send and receive over same port
172
multicastSocket.setReceiveBufferSize(15000);
173                multicastSocket.setSendBufferSize(10000);
174                multicastSocket.joinGroup(dscd.serverIP); // server IP for Multicast is really multicast
175
if(SessionUtilities.getVerbose())
176                   {
177                   rcvBuffSize = multicastSocket.getReceiveBufferSize();
178                   sndBuffSize = multicastSocket.getSendBufferSize();
179                   if(SessionUtilities.getVerbose())
180                      {
181                      System.out.println("Multicast socket max receive size is " + rcvBuffSize);
182                      System.out.println("Multicast socket max send size is " + sndBuffSize);
183                      }
184                   }
185                dscd.clientIP = dscd.serverIP;
186                //dscd.clientIP = multicastSocket.getLocalAddress(); doesn't seem to work
187
dscd.clientPort = multicastSocket.getLocalPort();
188                dscd.completelySpecified = true;
189                Thread JavaDoc me = new Thread JavaDoc(this,"DataShareConnectionFor"+dscd.channelDescription.channelName);
190                me.start();
191                keyValue = "Multicast-" + dscd.serverIP.getHostAddress()+":"+dscd.serverPort+"-"+dscd.clientIP.getHostAddress()+":"+dscd.clientPort;
192                while(!completed)
193                   {
194                   //System.out.println("waiting for connection thread to start...");
195
SessionUtilities.delay(100);
196                   }
197                }
198             catch(Exception JavaDoc e2)
199                {
200                System.out.println("Problems creating our multcastSocket...");
201                e2.printStackTrace();
202                throw new Exception JavaDoc(e2.toString());
203                }
204             break;
205             }
206          default:
207             {
208             System.out.println("DataShareConnection...unknown channel type!!!");
209             }
210          }
211       if(SessionUtilities.getVerbose())
212          System.out.println("DataShareConnection ready for "+ dscd.channelDescription.channelName);
213       }
214
215    public int getType()
216       {
217       return type;
218       }
219
220    public void
221    sendToOthers(Object JavaDoc object)
222       {
223       sendToOthers(object, false);
224       }
225
226    public void
227    sendToAll(Object JavaDoc object)
228       {
229       sendToAll(object, false);
230       }
231
232    public void
233    sendToClient(Object JavaDoc object, String JavaDoc clientUniqueName)
234       {
235       sendToClient(object, clientUniqueName, false);
236       }
237
238    public void
239    sendToOthers(Object JavaDoc object, boolean isControl)
240       {
241       try{
242          DataShareObject dsObject = new DataShareObject(SessionUtilities.convertObjectToByteArray(object),
243                                     DataShareObject.SENDTOOTHERS, dscd.clientKeyValue);
244          dsObject.isControlObject = isControl;
245          sendDSObject(dsObject);
246          }
247       catch(Exception JavaDoc e)
248          {
249          e.printStackTrace();
250          }
251       }
252
253    public void
254    sendToAll(Object JavaDoc object, boolean isControl)
255       {
256       try{
257          DataShareObject dsObject = new DataShareObject(SessionUtilities.convertObjectToByteArray(object),
258                                     DataShareObject.SENDTOALL, dscd.clientKeyValue);
259          dsObject.isControlObject = isControl;
260          sendDSObject(dsObject);
261          }
262       catch(Exception JavaDoc e)
263          {
264          e.printStackTrace();
265          }
266       }
267
268    public void
269    sendToClient(Object JavaDoc object, String JavaDoc clientUniqueName, boolean isControl)
270       {
271       try{
272          DataShareObject dsObject = new DataShareObject(SessionUtilities.convertObjectToByteArray(object),
273                                     dscd.clientKeyValue, clientUniqueName);
274          dsObject.isControlObject = isControl;
275          sendDSObject(dsObject);
276          }
277       catch(Exception JavaDoc e)
278          {
279          e.printStackTrace();
280          }
281       }
282
283    private synchronized void
284    sendDSObject(DataShareObject dsObject)
285       {
286       switch(type)
287          {
288          case ChannelDescription.TCP:
289             {
290             try{
291                if(running)
292                   {
293                   if(SessionUtilities.getVerbose())
294                      System.out.println("Sending " + dsObject.objectBytes.length + " bytes over TCP socket " + dscd.clientPort + "->ServerPort"+dscd.serverPort);
295                   oos.writeObject(dsObject);
296                   oos.flush();
297                   }
298                }
299             catch(IOException JavaDoc ioe)
300                {
301                if(!closeAllCalled)
302                   {
303                   ioe.printStackTrace();
304                   closeAll();
305                   }
306                }
307             break;
308             }
309          case ChannelDescription.UDP:
310             {
311             try{
312                if(running)
313                   {
314                   byte[] sndBytes = SessionUtilities.convertObjectToByteArray(dsObject);
315                   sndPacket = new DatagramPacket JavaDoc(sndBytes, sndBytes.length, dscd.serverIP, dscd.serverPort);
316                   if(SessionUtilities.getVerbose())
317                      System.out.println("Sending "+ sndBytes.length+ " bytes over UDP socket " + dscd.clientPort + "->ServerPort"+dscd.serverPort);
318                   udpSocket.send(sndPacket);
319                   }
320                }
321             catch(IOException JavaDoc ioe2)
322                {
323                if(!closeAllCalled)
324                   {
325                   ioe2.printStackTrace();
326                   closeAll();
327                   }
328                }
329             break;
330             }
331          case ChannelDescription.MULTICAST:
332             {
333             try{
334                if(running)
335                   {
336                   byte[] sndBytes = SessionUtilities.convertObjectToByteArray(dsObject);
337                   sndPacket = new DatagramPacket JavaDoc(sndBytes, sndBytes.length, dscd.serverIP, dscd.serverPort);
338                   if(SessionUtilities.getVerbose())
339                      System.out.println("Sending "+ sndBytes.length+ " bytes over Multicast socket " + dscd.clientPort + "->ServerPort"+dscd.serverPort);
340                   multicastSocket.send(sndPacket);
341                   }
342                }
343             catch(IOException JavaDoc ioe2)
344                {
345                if(!closeAllCalled)
346                   {
347                   ioe2.printStackTrace();
348                   closeAll();
349                   }
350                }
351             break;
352             }
353          default:
354             System.out.println("*** Trying to send to an unknown type of Connection ***");
355             break;
356          }
357       }
358
359    /**
360     * returns -1 if invalid, otherwise returns the max size of the UDP socket receive buffer
361     */

362    public int
363    getRcvBuffSize()
364       {
365       return rcvBuffSize;
366       }
367
368    /**
369     * returns -1 if invalid, otherwise returns the max size of the UDP socket send buffer
370     */

371    public int
372    getSndBuffSize()
373       {
374       return sndBuffSize;
375       }
376
377    // loop for any received data...
378
public void run()
379       {
380       if(SessionUtilities.getVerbose())
381          System.out.println("waiting for data on " + dscd.channelDescription.channelName);
382       System.out.flush();
383       Object JavaDoc object;
384       int objectCount = 0;
385 //Thread.currentThread().setPriority(Thread.currentThread().getPriority() + 1);
386
try{
387          completed = true; // would like to sync this with the readObject line
388
while(running)
389             {
390             switch(type)
391                {
392                case ChannelDescription.TCP:
393                   {
394                   object = ois.readObject(); // wait for an object
395
if(SessionUtilities.getVerbose())
396                      System.out.println("received " + dscd.channelDescription.channelName + " object #" + ++objectCount);
397                   try{
398                      DataShareObject dso = (DataShareObject)object;
399                      // if it is a keepalive packet, don't send to application
400
if(dso.type != DataShareObject.KEEPALIVE)
401                         cdri.dataReceived(dso);
402                      }
403                   catch(ClassCastException JavaDoc cce)
404                      {
405                      System.out.println("Not DataShareObject for object #" + objectCount + ", data ignored");
406                      }
407                   break;
408                   }
409                case ChannelDescription.UDP:
410                   {
411                   try{
412                      rcvPacket = new DatagramPacket JavaDoc(new byte[9998], 9998);
413                      udpSocket.receive(rcvPacket);
414 // System.out.println("received " + dscd.channelDescription.channelName + " object #" + ++objectCount + " (" + rcvPacket.getLength() + ") bytes");
415
object = (Object JavaDoc)SessionUtilities.retrieveObject(rcvPacket.getData());
416                      try{
417                         DataShareObject dso = (DataShareObject)object;
418                         /////////// next two lines are for printing out only
419
Object JavaDoc o = SessionUtilities.retrieveObject(dso.objectBytes);
420                         if(SessionUtilities.getVerbose())
421                            System.out.println("DSO info: " + dso.objectBytes.length + " bytes in " + o.getClass().toString() );
422                         ///////////
423
cdri.dataReceived(dso);
424                         }
425                      catch(ClassCastException JavaDoc cce)
426                         {
427                         System.out.println("Not DataShareObject for object #" + objectCount + ", data ignored");
428                         cce.printStackTrace();
429                         }
430                      }
431                   catch(StreamCorruptedException JavaDoc sce)
432                      {
433                      System.out.println("Discarding UDP packet-> " + sce.getMessage());
434                      }
435                   catch(UTFDataFormatException JavaDoc udfe)
436                      {
437                      System.out.println("Discarding UDP packet-> " + udfe.getMessage());
438                      }
439                   break;
440                   }
441                case ChannelDescription.MULTICAST:
442                   {
443                   try{
444                      rcvPacket = new DatagramPacket JavaDoc(new byte[9998], 9998);
445                      multicastSocket.receive(rcvPacket);
446 // System.out.println("received " + dscd.channelDescription.channelName + " object #" + ++objectCount + " (" + rcvPacket.getLength() + ") bytes");
447
object = (Object JavaDoc)SessionUtilities.retrieveObject(rcvPacket.getData());
448                      try{
449                         DataShareObject dso = (DataShareObject)object;
450                         /////////// next two lines are for printing out only
451
Object JavaDoc o = SessionUtilities.retrieveObject(dso.objectBytes);
452                         if(SessionUtilities.getVerbose())
453                            System.out.println("DSO info: " + dso.objectBytes.length + " bytes in " + o.getClass().toString() );
454                         ///////////
455
// for Multicast, we get any objects we send, and we don't want to receive this one...
456
// if(!o.getClass().isInstance(new ActivateConnectionObject()))
457
if(!dso.isControlObject)
458                            cdri.dataReceived(dso);
459                         }
460                      catch(ClassCastException JavaDoc cce)
461                         {
462                         System.out.println("Not DataShareObject for object #" + objectCount + ", data ignored");
463                         cce.printStackTrace();
464                         }
465                      }
466                   catch(StreamCorruptedException JavaDoc sce)
467                      {
468                      System.out.println("Discarding Multicast packet-> " + sce.getMessage());
469                      }
470                   catch(UTFDataFormatException JavaDoc udfe)
471                      {
472                      System.out.println("Discarding Multicast packet-> " + udfe.getMessage());
473                      }
474                   break;
475                   }
476                }
477             }
478          }
479       catch(Exception JavaDoc e)
480          {
481          if(!closeAllCalled)
482            {
483             System.out.println("DataShareConnection trouble for " + this.keyValue);
484             e.printStackTrace();
485             closeAll();
486             }
487          }
488       }
489
490
491    /**
492     * this will close all streams and connections, ignoring any errors
493     */

494    public void
495    closeAll()
496       {
497       if(!closeAllCalled)
498          {
499          closeAllCalled = true;
500          running = false; // set to false to stop thread
501
if(tcpSocket != null)
502             {
503             try{
504                tcpSocket.close();
505                tcpSocket = null;
506                }
507             catch(Exception JavaDoc e){}
508             }
509          else if(udpSocket != null)
510             {
511             try{
512                udpSocket.close();
513                udpSocket = null;
514                }
515             catch(Exception JavaDoc e){}
516             }
517          else if(multicastSocket != null)
518             {
519             try{
520                multicastSocket.leaveGroup(dscd.serverIP);
521                multicastSocket.close();
522                multicastSocket = null;
523                }
524             catch(Exception JavaDoc e){}
525             }
526          cdri.connectionLost(this);
527          }
528       }
529
530    }
531
Popular Tags