Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: marauroa/net/NetworkServerManager.java


1   /* $Id: NetworkServerManager.java,v 1.9 2003/12/09 23:40:16 arianne_rpg Exp $ */
2   /***************************************************************************
3    *                      (C) Copyright 2003 - Marauroa                      *
4    ***************************************************************************
5    ***************************************************************************
6    *                                                                         *
7    *   This program is free software; you can redistribute it and/or modify  *
8    *   it under the terms of the GNU General Public License as published by  *
9    *   the Free Software Foundation; either version 2 of the License, or     *
10   *   (at your option) any later version.                                   *
11   *                                                                         *
12   ***************************************************************************/
13  package marauroa.net;
14  
15  import java.net.*;
16  import java.util.*;
17  import java.io.*;
18  import java.math.*;
19  
20  import marauroa.marauroad;
21  
22  /** The NetworkServerManager is the active entity of the marauroa.net package,
23   *  it is in charge of sending and recieving the packages from the network. */
24  public class NetworkServerManager
25    {
26    /** The server socket from where we recieve the packets. */
27    private DatagramSocket socket;
28    /** While keepRunning is true, we keep recieving messages */
29    private boolean keepRunning;  
30    /** isFinished is true when the thread has really exited. */
31    private boolean isfinished;
32    
33    /** A List of Message objects: List<Message> */
34    private List messages;    
35    
36    private MessageFactory msgFactory;  
37    private NetworkServerManagerRead readManager;
38    private NetworkServerManagerWrite writeManager;
39    
40    /** Constructor that opens the socket on the marauroa_PORT and start the thread
41        to recieve new messages from the network. */
42    public NetworkServerManager() throws SocketException
43      {    
44      marauroad.trace("NetworkServerManager",">");
45      try
46        {
47        /* Create the socket and set a timeout of 1 second */
48        socket=new DatagramSocket(NetConst.marauroa_PORT);
49        socket.setSoTimeout(1000);
50         
51        msgFactory=MessageFactory.getFactory();
52      
53        keepRunning=true;
54        isfinished=false;
55  
56      /* Because we access the list from several places we create a synchronized list. */    
57        messages=Collections.synchronizedList(new LinkedList());
58      
59        readManager=new NetworkServerManagerRead();
60        readManager.start();
61      
62        writeManager=new NetworkServerManagerWrite();
63        }
64      finally
65        {
66        marauroad.trace("NetworkServerManager","<");
67        }
68      }
69    
70    /** This method notify the thread to finish it execution */
71    public void finish()
72      {
73      marauroad.trace("NetworkServerManager::finish",">");
74      keepRunning=false;
75      
76      while(isfinished==false)
77        {
78        try
79          {
80          Thread.sleep(1000);
81          }
82        catch(java.lang.InterruptedException e)
83          {
84          }
85        }
86      
87      socket.close();
88      marauroad.trace("NetworkServerManager::finish","<");
89      }
90      
91    private synchronized void newMessageArrived()
92      {
93      notify();
94      }
95   
96    /** This method returns a Message from the list or block for timeout milliseconds
97     *  until a message is available or null if timeout happens.
98     *  @param timeout timeout time in milliseconds
99     *  @return a Message or null if timeout happens */
100   public synchronized Message getMessage(int timeout)
101     {
102     marauroad.trace("NetworkServerManager::getMessage",">");
103     try
104       {
105       if(messages.size()==0)
106         {
107         try
108           {
109           wait(timeout);
110           }
111         catch(InterruptedException e)
112           {
113           }
114         }
115     
116       if(messages.size()==0)
117         {
118         marauroad.trace("NetworkServerManager::getMessage","D","Message not available.");
119         return null;      
120         }
121       else
122         {  
123         marauroad.trace("NetworkServerManager::getMessage","D","Message returned.");
124         return (Message)messages.remove(0); 
125         }
126       }
127     finally
128       {
129       marauroad.trace("NetworkServerManager::getMessage","<");
130       }
131     }
132 
133   /** This method blocks until a message is available 
134    *  @return a Message*/
135   public synchronized Message getMessage()
136     {
137     marauroad.trace("NetworkServerManager::getMessage",">");
138     try
139       {
140       while(messages.size()==0)
141         {
142         try
143           {
144           wait();
145           }
146         catch(InterruptedException e)
147           {
148           }
149         }
150       
151       return (Message)messages.remove(0);
152       }
153     finally
154       {
155       marauroad.trace("NetworkServerManager::getMessage","<");
156       }
157     }
158     
159   /** This method add a message to be delivered to the client the message is pointed to.
160    *  @param msg the message to ve delivered. */
161   public synchronized void addMessage(Message msg)
162     {
163     marauroad.trace("NetworkServerManager::addMessage",">");
164     writeManager.write(msg);
165     marauroad.trace("NetworkServerManager::addMessage","<");
166     }       
167   
168   /** The active thread in charge of recieving messages from the network. */
169   class NetworkServerManagerRead extends Thread
170     {
171     public NetworkServerManagerRead()
172       {
173       super("NetworkServerManagerRead");
174       }
175     
176     /** Method that execute the reading. It runs as a active thread forever. */
177     public void run()
178       {
179       marauroad.trace("NetworkServerManagerRead::run",">");
180       while(keepRunning)
181         {
182         byte[] buffer=new byte[NetConst.UDP_PACKET_SIZE];
183         DatagramPacket packet=new DatagramPacket(buffer,buffer.length);
184         
185         try
186           {
187           socket.receive(packet);          
188           marauroad.trace("NetworkServerManagerRead::run","D","Received UDP Packet");
189 
190           Message msg=msgFactory.getMessage(packet.getData(),(InetSocketAddress)packet.getSocketAddress());
191           marauroad.trace("NetworkServerManagerRead::run","D","Received message: "+msg.toString());
192          
193           messages.add(msg);
194           newMessageArrived();
195           }
196         catch(java.net.SocketTimeoutException e)
197           {
198           /* We need the thread to check from time to time if user has requested
199            * an exit */
200           }
201         catch(IOException e)
202           {
203           /* Report the exception */
204           marauroad.trace("NetworkServerManagerRead::run","X",e.getMessage());
205           }
206         }
207 
208       isfinished=true;              
209       marauroad.trace("NetworkServerManagerRead::run","<");
210       }    
211     }        
212     
213   /** A wrapper class for sending messages to clients */
214   class NetworkServerManagerWrite
215     {
216     private int last_signature;
217     private String name;
218     
219     public NetworkServerManagerWrite()
220       {
221       last_signature=0;
222       name="NetworkServerManagerWrite";
223       }
224     
225     /** Method that execute the writting */
226    public void write(Message msg)
227      {
228       marauroad.trace("NetworkServerManagerWrite::write",">");
229      try
230        {
231        /* TODO: Looks like hardcoded, write it in a better way */
232        if(keepRunning)
233          {
234          ByteArrayOutputStream out=new ByteArrayOutputStream();
235          OutputSerializer s=new OutputSerializer(out);
236     
237          s.write(msg);
238       
239          byte[] buffer=out.toByteArray();
240          marauroad.trace("NetworkServerManagerWrite::write","D","Message size in bytes: "+buffer.length);
241 
242       int total=buffer.length/(NetConst.UDP_PACKET_SIZE-3)+1;
243       ++last_signature;
244       int remaining=buffer.length;
245       
246       for(int i=0;i<total;++i)
247         {
248         int size=0;
249         if((NetConst.UDP_PACKET_SIZE-3)>remaining)
250           {
251           size=remaining;
252           }
253         else
254           {
255           size=NetConst.UDP_PACKET_SIZE-3;
256             }
257             
258           remaining-=size;
259             
260           marauroad.trace("NetworkServerManagerWrite::write","D","Packet size: "+size);
261           marauroad.trace("NetworkServerManagerWrite::write","D","Bytes remaining: "+remaining);
262           
263         byte[] data=new byte[size+3];
264         data[0]=(byte)total;
265         data[1]=(byte)i;
266         data[2]=(byte)last_signature;
267         System.arraycopy(buffer,(NetConst.UDP_PACKET_SIZE-3)*i,data,3,size);
268 
269              DatagramPacket pkt=new DatagramPacket(data,data.length,msg.getAddress());        
270             socket.send(pkt);
271             marauroad.trace("NetworkServerManagerWrite::write","D","Sent packet "+(i+1)+" of "+total);
272         }
273         
274           marauroad.trace("NetworkServerManagerWrite::write","D","Sent message: "+msg.toString());
275          }
276        }
277      catch(IOException e)
278        {    
279         /* Report the exception */
280         marauroad.trace("NetworkServerManagerWrite::write","X",e.getMessage());
281        }
282      finally
283        {
284         marauroad.trace("NetworkServerManagerWrite::write","<");
285         }
286      }
287     }    
288   }