1:  
2:   /**
3:    * Abstract class AbstractServer.
4:    * La classe AbstractServer  ralise une abstraction/encapsulation
5:    * de la classe java.net.ServerSocket, un utilisateur de cette classe
6:    * doit seulement prciser le port et le protocole de ce serveur.
7:    * La stratgie du serveur est fonction de l'implmentation de la
8:    * mthode executeConnexion  laisse abstraite. 
9:    
10:    @author Laurent Dehoey I177416
11:    @version 23/01/2003
12:    */
13:  
14:   //import java.io.*;
15:  
16:   //The Runnable interface should be implemented by any class whose
17:   //instances are intended to be executed by a thread. The class must
18:   //define a method of no arguments called run
19:   //...
20:   //In addition, Runnable provides the means for a class to be active
21:   //while not subclassing Thread. A class that implements Runnable
22:   //can run without subclassing Thread by instantiating a Thread
23:   //instance and passing itself in as the target. In most cases, the
24:   //Runnable interface should be used if you are only planning to
25:   //override the run() method and no other Thread methods. This is
26:   //important because classes should not be subclassed unless the
27:   //programmer intends on modifying or enhancing the fundamental behavior
28:   //of the class. 
29:   //...
30:   //public void run()
31:   //When an object implementing interface Runnable is used to create
32:   //a thread, starting the thread causes the object's run method to be
33:   //called in that separately executing thread. 
34:   //The general contract of the method run is that it may take any action whatsoever. 
35:  
36:  
37:   public abstract class AbstractServer implements Runnable{
38:      //dclarations des donnes d'instance  complter
39:  
40:      /**
41:       * Le nombre de connection
42:       * protected ca veut dire que ce sont
43:       * nos classes filles qui soit lisent
44:       * soit mettent  jour cet attibut ?
45:       * le nombre de requete que ce
46:       * serveur a servi ? ou le nombre
47:       * de requetes courantes ? qu'il est
48:       * en train de servir ?
49:       
50:       */
51:      protected long connections;
52:  
53:       /**
54:        * compteur statistique static du nombre
55:        * de connections effectues avec
56:        * AbstractServer
57:        */
58:      protected static int globalStaticConnections;
59:      
60:       /**
61:        * compteur statistique du nombre
62:        * de connections effectues avec
63:        * AbstractServer
64:        */
65:      protected int globalInstanceConnections;
66:      
67:      /**
68:       * Le Thread associ en local
69:       * on va lui donner un petit nom pour les affichages
70:       */
71:      private java.lang.Thread local;
72:  
73:      /**Le port associ au server*/
74:      protected int port;
75:  
76:      /*Le protocol de communication*/
77:      protected Protocol protocol;
78:  
79:      /**Le serveur de "socket"*/
80:      private java.net.ServerSocket server;
81:  
82:      /**
83:       * Delai de garde en millisecondes afin que le serveur
84:       * puisse s'arreter d'apres la doc de AbstractServer
85:       * sur le site des TP
86:       * Private et pas de setTIME_OUT(int tmo) methode ?
87:       * donc y a pas le choix ?!!
88:       */
89:      
90:      private int TIME_OUT=6000;//6 secondes
91:  
92:      /**Reflete l'etat du mode trace*/
93:      protected boolean verbose=true;
94:      
95:  
96:      /**
97:       * Constructeur d'AbstractServer
98:       @param protocol Protocol le protocol que vont "causer" le serveur et le client
99:       @param port int le numro de port sur lequel il vont se brancher
100:       */
101:      
102:      public AbstractServer(Protocol protocolint portthrows java.io.IOException
103:      {
104:      
105:        this.protocol = protocol;
106:        this.port = port;
107:        /**
108:         * Creates a server socket, bound to the specified port.
109:         * A port of 0 creates a socket on any free port.
110:         * The maximum queue length for incoming connection indications
111:         * (a request to connect) is set to 50. If a connection indication
112:         * arrives when the queue is full, the connection is refused. 
113:         */
114:        server = new java.net.ServerSocket(port);
115:        /**
116:         * Ici il s'agit de n'ecouter que pendant un
117:         * certain laps de temps les clients arriver
118:         * car on a fix TIME_OUT  une valeur /= de zero(infini)
119:         * pass ce delai on sort du accept...et on
120:         * fait quoi alors ? le serveur s'arrete ? le thread
121:         * s'arrete ? le serveur interrompt le thread pendant
122:         * TIME_OUT milliseconde et le relance ?
123:         */
124:        server.setSoTimeout(TIME_OUT)
125:        /**
126:         * c'est dans le thead que ca va se passer la connection
127:         */
128:        local = new Thread(this,"DaAbstracServer/Id:"+(int)(1000*java.lang.Math.random()));
129:        local.setPriority(Thread.MAX_PRIORITY);
130:        local.start();
131:     }
132:  
133:     /**
134:      * On feeeeerme !
135:      * c'est  dire quu'on interrompt le thread ?
136:      * qu'on ferme le socket ouvert ? qu'on ferme
137:      * le socket en blockage d'accept (lui meme en
138:      * attente pendant TIME_OUT ms)
139:      * interrompre ca ne veut pas dire tuer ?
140:      * ca veux juste dire mettre en pause pour
141:      * laisser reprendre par la suite non ?
142:      @return void
143:      */
144:     public void interrupt(){
145:       //est-ce qu'on peut interrompre le serveur
146:       //s'il est train de servir des clients ?
147:       //non evidemment !!
148:       //mais on pourrait essayer...en random 1 fois sur 2?
149:       if (connections>0){
150:           if (getVerbose())
151:           {
152:               System.out.println("Qui a os tenter de m'interrompre moi : " +local.toString()+"?!!!\n");
153:               System.out.println("Alors qu'il y a encore "+connections+" connections actives !\n");
154:               }
155:               int i=(int)((int)100*java.lang.Math.random())%2;
156:               if(getVerbose())System.out.println(i);
157:   //        if( 0 == i){
158:               if (false){
159:               if (getVerbose()){
160:                   System.out.println("Oui on va t'interrompre si on veut....glups");
161:                   System.out.println("mais on va couper les socket");
162:                   System.out.println("et on ne te fais pas dormir sur ce coup l...");
163:                   System.out.println("..on va te tuer tout simplement...");
164:                   }
165:                   try{
166:                   server.close();
167:                   local.dumpStack();
168:                   local.destroy();
169:                   }catch(java.io.IOException ioe)
170:                   {
171:                       System.out.println("Difficile  fermer le server ?!");
172:                   }
173:                   local.interrupt();
174:          }else  if (getVerbose()){
175:               System.out.println("Ok on va te laisser en continuer :-)");
176:          }
177:  
178:       }else {
179:           if(getVerbose()){
180:               System.out.println("Ok on va se coucher: " +local.toString()+"\n");
181:           }
182:           try{
183:   /**
184:    * http://java.sun.com/docs/books/tutorial/essential/threads/index.html
185:    * http://java.sun.com/products/jdk/1.2/docs/guide/misc/threadPrimitiveDeprecation.html
186:    * What should I use instead of Thread.stop?
187:    * Most uses of stop should be replaced by code that simply modifies some variable to indicate
188:    * that the target thread should stop running. The target thread should check this variable
189:    * regularly, and return from its run method in an orderly fashion if the variable indicates
190:    * that it is to stop running. (This is the approach that JavaSoft's Tutorial has always recommended.)
191:    * To ensure prompt communication of the stop-request, the variable must be volatile (or access
192:    * to the variable must be synchronized).
193:    */
194:  
195:           //on s'endore un peu le temps de laisser accept "time_outer"
196:           if (getVerbose()){
197:            System.out.println(local.toString()+" Will going to sleep for "+TIME_OUT+"ms before being interrupted");
198:           }
199:           local.sleep(TIME_OUT);
200:           local.interrupt();
201:  
202:           
203:           }catch(InterruptedException ie){
204:            System.out.println(local.toString()+" : Hahum j'ai dormi longtemps ?");
205:  
206:           }catch(SecurityException se){
207:             System.out.println(local.toString()+" : Humppf quoi ?!!");
208:           }
209:      }
210:       
211:       // completer
212:       
213:  
214:     }
215:     public boolean getVerbose(){
216:       return verbose;
217:     }
218:     public void setVerbose(boolean verbose){
219:     if (verbose)
220:      System.out.println("Hoho U want a verbose port "+port+" !\n");
221:     this.verbose = verbose;
222:    }
223:     public Protocol getProtocol(){
224:       return protocol;
225:    }
226:     public void setProtocol(Protocol protocol){
227:       this.protocol = protocol;
228:    }
229:  
230:       /**
231:        * le corps de thread d'ecoute et qui va
232:        * lancer le type de connection...
233:        */
234:       
235:     public void run(){
236:       if(local==Thread.currentThread()){
237:         while(true){//on Choisi de boucler indfiniment quelque soir le timeout
238:                     //de l'accept() ?
239:                     //on va donc pouvoir se faire arreter ?
240:                     //il faudrait qu'on puisse nous reprer pour cela...
241:         try{
242:          //normalement getVerbose devrait etre  vrai meme au premier appel
243:          //juste apres le start()
244:          //mais non ... ca c'est un mystre pour moi 
245:           if(getVerbose())
246:               System.out.println("Accepting request\n");
247:               //il semble qu'il ne soit pas possible de fixer le mode
248:               //verbose avant cette ligne...
249:               else System.out.println("!getVerbose()?!?\n");
250:             
251:            if (local.interrupted()){
252:            //Le serveur a ete interrompu
253:            System.out.println(local.toString()+" bon bah voila je reessaye un accept pendant "+TIME_OUT+"ms...");
254:            }
255:             
256:               /**
257:                * le serveur se met  l'ecoute des clients
258:                * potentiel pendant TIME_OUT ms
259:                * si tout se passe bien on recupere alors
260:                * un socket de "connection" client en sortie
261:                */
262:               
263:               if (server.isClosed())throw(new java.net.SocketException());
264:                java.net.Socket client=server.accept();
265:               
266:           //il y a pas eu de time out
267:           //on va servir un client
268:           if(getVerbose())
269:               System.out.println("Haaa a client on port : "+port+"\n");
270:           if(getVerbose())
271:               System.out.println("Fireing subclass executeConnection\n");
272:  
273:               /**
274:                * Socket qu'on transmet  notre methode, ici abstraite,
275:                * mais implmente dans nos sub-classes
276:                */
277:               //un thread va s'occuper d'un client connect
278:               //on incremente la connection ici ?
279:           connections++;
280:           //et c'est la methode executeConnection(client) implmente
281:           //qui dcremente  la sortie ?
282:           //humpf ?! pas terrible non ?
283:           //finalement ca marche assez bien :-)
284:           executeConnection(client);
285:           //executeConnection doit nous rendre la main assez vite
286:           //en particulier si elle est aussi multithreade non ?
287:           //meme si on ne sait pas si oui ou nous elle l'est
288:           //et comment elle l'est...Pattern Strategy
289:           if(getVerbose())
290:               System.out.println("Was that " + ++globalInstanceConnections "/" + ++globalStaticConnections +"th executeConnection fine ?\n");
291:          }catch(java.net.SocketTimeoutException st){
292:               System.out.println("TimeOut: " st +"\n");
293:               System.out.println("Trying to interrupt server thread: "+local.toString()+"\n");
294:               this.interrupt();
295:          }catch(java.io.IOException e){
296:               System.out.println("Argaa " e);
297:          }
298:        }
299:       }
300:     }
301:     /**
302:      
303:      * da methode que nos serveur se doivent d'implementer dans
304:      * le pattern strategy
305:      */
306:     
307:      public abstract void executeConnection(java.net.Socket s);
308:   }
309:      
310:  

This page was automatically generated by SharpDevelop.