KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > dyade > aaa > agent > StreamNetwork


1 /*
2  * Copyright (C) 2001 - 2004 ScalAgent Distributed Technologies
3  * Copyright (C) 2004 - France Telecom R&D
4  * Copyright (C) 1996 - 2000 BULL
5  * Copyright (C) 1996 - 2000 INRIA
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20  * USA.
21  *
22  * Initial developer(s): Dyade
23  * Contributor(s): ScalAgent Distributed Technologies
24  */

25 package fr.dyade.aaa.agent;
26
27 import java.io.*;
28 import java.util.Vector JavaDoc;
29 import java.util.Enumeration JavaDoc;
30 import java.net.Socket JavaDoc;
31 import java.net.ServerSocket JavaDoc;
32 import java.net.InetAddress JavaDoc;
33 import java.net.ConnectException JavaDoc;
34 import java.net.BindException JavaDoc;
35 import java.net.UnknownHostException JavaDoc;
36 import java.net.SocketException JavaDoc;
37
38 import org.objectweb.util.monolog.api.BasicLevel;
39 import org.objectweb.util.monolog.api.Logger;
40
41 import fr.dyade.aaa.util.SocketAddress;
42
43 /**
44  * <code>StreamNetwork</code> is a base implementation of <code>Network</code>
45  * class for TCP sockets.
46  */

47 public abstract class StreamNetwork extends Network {
48   /**
49    * Numbers of attempt to bind the server's socket before aborting,
50    * default value is 3.
51    * This value can be adjusted for all network components by setting
52    * <code>CnxRetry</code> global property or for a particular network
53    * by setting <code>\<DomainName\>.CnxRetry</code> specific property.
54    * <p>
55    * Theses properties can be fixed either from <code>java</code> launching
56    * command, or in <code>a3servers.xml</code> configuration file.
57    */

58   int CnxRetry = 3;
59   /**
60    * The maximum queue length for incoming connection indications,
61    * default value is 5.
62    * This value can be adjusted for all network components by setting
63    * <code>backlog</code> global property or for a particular network
64    * by setting <code>\<DomainName\>.backlog</code> specific property.
65    * <p>
66    * Theses properties can be fixed either from <code>java</code> launching
67    * command, or in <code>a3servers.xml</code> configuration file.
68    */

69   int backlog = 5;
70   /**
71    * Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm),
72    * default value is false.
73    * This value can be adjusted for all network components by setting
74    * <code>TcpNoDelay</code> global property or for a particular network
75    * by setting <code>\<DomainName\>.TcpNoDelay</code> specific property.
76    * <p>
77    * Theses properties can be fixed either from <code>java</code> launching
78    * command, or in <code>a3servers.xml</code> configuration file.
79    */

80   boolean TcpNoDelay = false;
81   /**
82    * Enable SO_LINGER with the specified linger time in seconds, if the
83    * value is less than 0 then it disables SO_LINGER. Default value is -1.
84    * This value can be adjusted for all network components by setting
85    * <code>TcpNoDelay</code> global property or for a particular network
86    * by setting <code>\<DomainName\>.TcpNoDelay</code> specific property.
87    * <p>
88    * Theses properties can be fixed either from <code>java</code> launching
89    * command, or in <code>a3servers.xml</code> configuration file.
90    */

91   int SoLinger = -1;
92   /**
93    * Enable/disabl SO_TIMEOUT with the specified timeout in milliseconds.
94    * The timeout must be > 0. A timeout of zero is interpreted as an infinite
95    * timeout.
96    * This value can be adjusted for all network components by setting
97    * <code>SoTimeout</code> global property or for a particular network
98    * by setting <code>\<DomainName\>.SoTimeout</code> specific property.
99    * <p>
100    * Theses properties can be fixed either from <code>java</code> launching
101    * command, or in <code>a3servers.xml</code> configuration file.
102    */

103   int SoTimeout = 0;
104
105   /** Creates a new Network component */
106   public StreamNetwork() {
107     super();
108   }
109
110   /**
111    * Initializes a new <tt>StreamNetwork</tt> component.
112    *
113    * @see Network
114    *
115    * @param name The domain name.
116    * @param port The listen port.
117    * @param servers The list of servers directly accessible from this
118    * network interface.
119    */

120   public void init(String JavaDoc name, int port, short[] servers) throws Exception JavaDoc {
121     super.init(name, port, servers);
122
123     CnxRetry = Integer.getInteger("CnxRetry", CnxRetry).intValue();
124     CnxRetry = Integer.getInteger(name + ".CnxRetry", CnxRetry).intValue();
125
126     backlog = Integer.getInteger("backlog", backlog).intValue();
127     backlog = Integer.getInteger(name + ".backlog", backlog).intValue();
128
129     TcpNoDelay = Boolean.getBoolean(name + ".TcpNoDelay");
130     if (! TcpNoDelay) TcpNoDelay = Boolean.getBoolean("TcpNoDelay");
131
132     SoLinger = Integer.getInteger("SoLinger", SoLinger).intValue();
133     SoLinger = Integer.getInteger(name + ".SoLinger", SoLinger).intValue();
134
135     SoTimeout = Integer.getInteger("SoTimeout", SoTimeout).intValue();
136     SoTimeout = Integer.getInteger(name + ".SoTimeout", SoTimeout).intValue();
137   }
138
139   /**
140    * This method creates and returns a socket connected to a
141    * specified server. It may be overloaded in subclass, in order
142    * to create particular subclasses of sockets.
143    *
144    * @param server the server descriptor.
145    * @return a socket connected to a ServerSocket at the specified
146    * network address and port.
147    *
148    * @exception IOException if the connection can't be established
149    */

150   final Socket JavaDoc createSocket(ServerDesc server) throws IOException {
151     for (Enumeration JavaDoc e = server.getSockAddrs(); e.hasMoreElements();) {
152       SocketAddress sa = (SocketAddress) e.nextElement();
153
154       if (this.logmon.isLoggable(BasicLevel.DEBUG))
155         this.logmon.log(BasicLevel.DEBUG,
156                         this.getName() + ", try to connect server#" +
157                         server.getServerId() +
158                         ", addr=" + sa.getHostname() +
159                         ", port=" + sa.getPort());
160                   
161       try {
162         Socket JavaDoc socket = createSocket(sa);
163
164         if (this.logmon.isLoggable(BasicLevel.DEBUG))
165           this.logmon.log(BasicLevel.DEBUG, this.getName() + ", connected");
166
167         // Memorize the right address for next try.
168
server.moveToFirst(sa);
169         return socket;
170       } catch (IOException exc) {
171         this.logmon.log(BasicLevel.DEBUG,
172                         this.getName() + ", connection refused, try next element");
173         continue;
174       }
175     }
176            
177     throw new ConnectException JavaDoc("Cannot connect to server#" + server.getServerId());
178   }
179
180   /**
181    * This method creates and returns a socket connected to a ServerSocket at
182    * the specified socket address. If it fails it resets the address in order
183    * to take in account dynamic DNS.
184    *
185    * @param addr the socket address.
186    * @return a socket connected to a ServerSocket at the specified
187    * network address and port.
188    *
189    * @exception IOException if the connection can't be established
190
191    */

192   final Socket JavaDoc createSocket(SocketAddress addr) throws IOException {
193     try {
194       return createSocket(addr.getAddress(), addr.getPort());
195     } catch (IOException exc) {
196       this.logmon.log(BasicLevel.DEBUG,
197                       this.getName() + ", connection refused, reset addr");
198       addr.resetAddr();
199       return createSocket(addr.getAddress(), addr.getPort());
200     }
201   }
202
203   /**
204    * This method creates and returns a socket connected to a ServerSocket at
205    * the specified network address and port. It may be overloaded in subclass,
206    * in order to create particular subclasses of sockets.
207    * <p>
208    * Due to polymorphism of both factories and sockets, different kinds of
209    * sockets can be used by the same application code. The sockets returned
210    * to the application can be subclasses of <a HREF="java.net.Socket">
211    * Socket</a>, so that they can directly expose new APIs for features such
212    * as compression, security, or firewall tunneling.
213    *
214    * @param host the server host.
215    * @param port the server port.
216    * @return a socket connected to a ServerSocket at the specified
217    * network address and port.
218    *
219    * @exception IOException if the connection can't be established
220    */

221   Socket JavaDoc createSocket(InetAddress JavaDoc host, int port) throws IOException {
222     if (host == null)
223       throw new UnknownHostException JavaDoc();
224     return new Socket JavaDoc(host, port);
225   }
226
227   /**
228    * This method creates and returns a server socket which uses all network
229    * interfaces on the host, and is bound to the specified port.
230    *
231    * @return a server socket bound to the specified port.
232    *
233    * @exception IOException for networking errors
234    */

235   final ServerSocket JavaDoc createServerSocket() throws IOException {
236     for (int i=0; ; i++) {
237       try {
238         return createServerSocket(port);
239       } catch (BindException JavaDoc exc) {
240         if (i > CnxRetry) throw exc;
241         try {
242           Thread.sleep(i * 200);
243         } catch (InterruptedException JavaDoc e) {}
244       }
245     }
246   }
247
248   /**
249    * This method creates and returns a server socket which uses all network
250    * interfaces on the host, and is bound to the specified port. It may be
251    * overloaded in subclass, in order to create particular subclasses of
252    * server sockets.
253    *
254    * @param port the port to listen to.
255    * @return a server socket bound to the specified port.
256    *
257    * @exception IOException for networking errors
258    */

259   ServerSocket JavaDoc createServerSocket(int port) throws IOException {
260     return new ServerSocket JavaDoc(port, backlog);
261   }
262
263   /**
264    * Configures this socket using the socket options established for this
265    * factory. It may be overloaded in subclass, in order to handle particular
266    * subclasses of sockets
267    *
268    * @param Socket the socket.
269    *
270    * @exception IOException for networking errors
271    */

272   void setSocketOption(Socket JavaDoc sock) throws SocketException JavaDoc {
273     // TCP data coalescing - ie Nagle's algorithm
274
sock.setTcpNoDelay(TcpNoDelay);
275     // Read operation will block indefinitely until requested data arrives
276
sock.setSoTimeout(SoTimeout);
277     // Linger-on-Close timeout.
278
if (SoLinger >= 0)
279       sock.setSoLinger(true, SoLinger);
280     else
281       sock.setSoLinger(false, 0);
282   }
283 }
284
Popular Tags