Source Code Cross Referenced for TCPEndpoint.java in  » 6.0-JDK-Modules-sun » rmi » sun » rmi » transport » tcp » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules sun » rmi » sun.rmi.transport.tcp 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 1996-2005 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:        package sun.rmi.transport.tcp;
026:
027:        import java.io.DataInput;
028:        import java.io.DataOutput;
029:        import java.io.IOException;
030:        import java.io.ObjectInput;
031:        import java.io.ObjectOutput;
032:        import java.net.InetAddress;
033:        import java.net.ServerSocket;
034:        import java.net.Socket;
035:        import java.rmi.ConnectIOException;
036:        import java.rmi.RemoteException;
037:        import java.rmi.server.RMIClientSocketFactory;
038:        import java.rmi.server.RMIServerSocketFactory;
039:        import java.rmi.server.RMISocketFactory;
040:        import java.security.AccessController;
041:        import java.util.Collection;
042:        import java.util.HashMap;
043:        import java.util.HashSet;
044:        import java.util.LinkedList;
045:        import java.util.Map;
046:        import java.util.Set;
047:        import sun.rmi.runtime.Log;
048:        import sun.rmi.runtime.NewThreadAction;
049:        import sun.rmi.transport.Channel;
050:        import sun.rmi.transport.Endpoint;
051:        import sun.rmi.transport.Target;
052:        import sun.rmi.transport.Transport;
053:        import sun.security.action.GetBooleanAction;
054:        import sun.security.action.GetIntegerAction;
055:        import sun.security.action.GetPropertyAction;
056:
057:        /**
058:         * TCPEndpoint represents some communication endpoint for an address
059:         * space (VM).
060:         *
061:         * @author Ann Wollrath
062:         */
063:        public class TCPEndpoint implements  Endpoint {
064:            /** IP address or host name */
065:            private String host;
066:            /** port number */
067:            private int port;
068:            /** custom client socket factory (null if not custom factory) */
069:            private final RMIClientSocketFactory csf;
070:            /** custom server socket factory (null if not custom factory) */
071:            private final RMIServerSocketFactory ssf;
072:
073:            /** if local, the port number to listen on */
074:            private int listenPort = -1;
075:            /** if local, the transport object associated with this endpoint */
076:            private TCPTransport transport = null;
077:
078:            /** the local host name */
079:            private static String localHost;
080:            /** true if real local host name is known yet */
081:            private static boolean localHostKnown;
082:
083:            // this should be a *private* method since it is privileged
084:            private static int getInt(String name, int def) {
085:                return AccessController.doPrivileged(new GetIntegerAction(name,
086:                        def));
087:            }
088:
089:            // this should be a *private* method since it is privileged
090:            private static boolean getBoolean(String name) {
091:                return AccessController
092:                        .doPrivileged(new GetBooleanAction(name));
093:            }
094:
095:            /**
096:             * Returns the value of the java.rmi.server.hostname property.
097:             */
098:            private static String getHostnameProperty() {
099:                return AccessController.doPrivileged(new GetPropertyAction(
100:                        "java.rmi.server.hostname"));
101:            }
102:
103:            /**
104:             * Find host name of local machine.  Property "java.rmi.server.hostname"
105:             * is used if set, so server administrator can compensate for the possible
106:             * inablility to get fully qualified host name from VM.
107:             */
108:            static {
109:                localHostKnown = true;
110:                localHost = getHostnameProperty();
111:
112:                // could try querying CGI program here?
113:                if (localHost == null) {
114:                    try {
115:                        InetAddress localAddr = InetAddress.getLocalHost();
116:                        byte[] raw = localAddr.getAddress();
117:                        if ((raw[0] == 127) && (raw[1] == 0) && (raw[2] == 0)
118:                                && (raw[3] == 1)) {
119:                            localHostKnown = false;
120:                        }
121:
122:                        /* if the user wishes to use a fully qualified domain
123:                         * name then attempt to find one.  
124:                         */
125:                        if (getBoolean("java.rmi.server.useLocalHostName")) {
126:                            localHost = FQDN.attemptFQDN(localAddr);
127:                        } else {
128:                            /* default to using ip addresses, names will 
129:                             * work across seperate domains. 
130:                             */
131:                            localHost = localAddr.getHostAddress();
132:                        }
133:                    } catch (Exception e) {
134:                        localHostKnown = false;
135:                        localHost = null;
136:                    }
137:                }
138:
139:                if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
140:                    TCPTransport.tcpLog.log(Log.BRIEF, "localHostKnown = "
141:                            + localHostKnown + ", localHost = " + localHost);
142:                }
143:            }
144:
145:            /** maps an endpoint key containing custom socket factories to
146:             * their own unique endpoint */
147:            // TBD: should this be a weak hash table?
148:            private static final Map<TCPEndpoint, LinkedList<TCPEndpoint>> localEndpoints = new HashMap<TCPEndpoint, LinkedList<TCPEndpoint>>();
149:
150:            /**
151:             * Create an endpoint for a specified host and port.
152:             * This should not be used by external classes to create endpoints
153:             * for servers in this VM; use getLocalEndpoint instead.
154:             */
155:            public TCPEndpoint(String host, int port) {
156:                this (host, port, null, null);
157:            }
158:
159:            /**
160:             * Create a custom socket factory endpoint for a specified host and port.
161:             * This should not be used by external classes to create endpoints
162:             * for servers in this VM; use getLocalEndpoint instead.
163:             */
164:            public TCPEndpoint(String host, int port,
165:                    RMIClientSocketFactory csf, RMIServerSocketFactory ssf) {
166:                if (host == null)
167:                    host = "";
168:                this .host = host;
169:                this .port = port;
170:                this .csf = csf;
171:                this .ssf = ssf;
172:            }
173:
174:            /**
175:             * Get an endpoint for the local address space on specified port.
176:             * If port number is 0, it returns shared default endpoint object
177:             * whose host name and port may or may not have been determined.
178:             */
179:            public static TCPEndpoint getLocalEndpoint(int port) {
180:                return getLocalEndpoint(port, null, null);
181:            }
182:
183:            public static TCPEndpoint getLocalEndpoint(int port,
184:                    RMIClientSocketFactory csf, RMIServerSocketFactory ssf) {
185:                /*
186:                 * Find mapping for an endpoint key to the list of local unique
187:                 * endpoints for this client/server socket factory pair (perhaps
188:                 * null) for the specific port.
189:                 */
190:                TCPEndpoint ep = null;
191:
192:                synchronized (localEndpoints) {
193:                    TCPEndpoint endpointKey = new TCPEndpoint(null, port, csf,
194:                            ssf);
195:                    LinkedList<TCPEndpoint> epList = localEndpoints
196:                            .get(endpointKey);
197:                    String localHost = resampleLocalHost();
198:
199:                    if (epList == null) {
200:                        /*
201:                         * Create new endpoint list.
202:                         */
203:                        ep = new TCPEndpoint(localHost, port, csf, ssf);
204:                        epList = new LinkedList<TCPEndpoint>();
205:                        epList.add(ep);
206:                        ep.listenPort = port;
207:                        ep.transport = new TCPTransport(epList);
208:                        localEndpoints.put(endpointKey, epList);
209:
210:                        if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
211:                            TCPTransport.tcpLog.log(Log.BRIEF,
212:                                    "created local endpoint for socket factory "
213:                                            + ssf + " on port " + port);
214:                        }
215:                    } else {
216:                        synchronized (epList) {
217:                            ep = epList.getLast();
218:                            String lastHost = ep.host;
219:                            int lastPort = ep.port;
220:                            TCPTransport lastTransport = ep.transport;
221:                            // assert (localHost == null ^ lastHost != null)
222:                            if (localHost != null
223:                                    && !localHost.equals(lastHost)) {
224:                                /*
225:                                 * Hostname has been updated; add updated endpoint
226:                                 * to list.
227:                                 */
228:                                if (lastPort != 0) {
229:                                    /*
230:                                     * Remove outdated endpoints only if the
231:                                     * port has already been set on those endpoints.
232:                                     */
233:                                    epList.clear();
234:                                }
235:                                ep = new TCPEndpoint(localHost, lastPort, csf,
236:                                        ssf);
237:                                ep.listenPort = port;
238:                                ep.transport = lastTransport;
239:                                epList.add(ep);
240:                            }
241:                        }
242:                    }
243:                }
244:
245:                return ep;
246:            }
247:
248:            /**
249:             * Resamples the local hostname and returns the possibly-updated
250:             * local hostname.
251:             */
252:            private static String resampleLocalHost() {
253:
254:                String hostnameProperty = getHostnameProperty();
255:
256:                synchronized (localEndpoints) {
257:                    // assert(localHostKnown ^ (localHost == null))
258:
259:                    if (hostnameProperty != null) {
260:                        if (!localHostKnown) {
261:                            /*
262:                             * If the local hostname is unknown, update ALL
263:                             * existing endpoints with the new hostname.
264:                             */
265:                            setLocalHost(hostnameProperty);
266:                        } else if (!hostnameProperty.equals(localHost)) {
267:                            /*
268:                             * Only update the localHost field for reference
269:                             * in future endpoint creation.
270:                             */
271:                            localHost = hostnameProperty;
272:
273:                            if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
274:                                TCPTransport.tcpLog.log(Log.BRIEF,
275:                                        "updated local hostname to: "
276:                                                + localHost);
277:                            }
278:                        }
279:                    }
280:                    return localHost;
281:                }
282:            }
283:
284:            /**
285:             * Set the local host name, if currently unknown.
286:             */
287:            static void setLocalHost(String host) {
288:                // assert (host != null)
289:
290:                synchronized (localEndpoints) {
291:                    /*
292:                     * If host is not known, change the host field of ALL
293:                     * the local endpoints.
294:                     */
295:                    if (!localHostKnown) {
296:                        localHost = host;
297:                        localHostKnown = true;
298:
299:                        if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
300:                            TCPTransport.tcpLog.log(Log.BRIEF,
301:                                    "local host set to " + host);
302:                        }
303:                        for (LinkedList<TCPEndpoint> epList : localEndpoints
304:                                .values()) {
305:                            synchronized (epList) {
306:                                for (TCPEndpoint ep : epList) {
307:                                    ep.host = host;
308:                                }
309:                            }
310:                        }
311:                    }
312:                }
313:            }
314:
315:            /**
316:             * Set the port of the (shared) default endpoint object.
317:             * When first created, it contains port 0 because the transport
318:             * hasn't tried to listen to get assigned a port, or if listening
319:             * failed, a port hasn't been assigned from the server.
320:             */
321:            static void setDefaultPort(int port, RMIClientSocketFactory csf,
322:                    RMIServerSocketFactory ssf) {
323:                TCPEndpoint endpointKey = new TCPEndpoint(null, 0, csf, ssf);
324:
325:                synchronized (localEndpoints) {
326:                    LinkedList<TCPEndpoint> epList = localEndpoints
327:                            .get(endpointKey);
328:
329:                    synchronized (epList) {
330:                        int size = epList.size();
331:                        TCPEndpoint lastEp = epList.getLast();
332:
333:                        for (TCPEndpoint ep : epList) {
334:                            ep.port = port;
335:                        }
336:                        if (size > 1) {
337:                            /*
338:                             * Remove all but the last element of the list
339:                             * (which contains the most recent hostname).
340:                             */
341:                            epList.clear();
342:                            epList.add(lastEp);
343:                        }
344:                    }
345:
346:                    /*
347:                     * Allow future exports to use the actual bound port
348:                     * explicitly (see 6269166).
349:                     */
350:                    TCPEndpoint newEndpointKey = new TCPEndpoint(null, port,
351:                            csf, ssf);
352:                    localEndpoints.put(newEndpointKey, epList);
353:
354:                    if (TCPTransport.tcpLog.isLoggable(Log.BRIEF)) {
355:                        TCPTransport.tcpLog.log(Log.BRIEF,
356:                                "default port for server socket factory " + ssf
357:                                        + " and client socket factory " + csf
358:                                        + " set to " + port);
359:                    }
360:                }
361:            }
362:
363:            /**
364:             * Returns transport for making connections to remote endpoints;
365:             * (here, the default transport at port 0 is used).
366:             */
367:            public Transport getOutboundTransport() {
368:                TCPEndpoint localEndpoint = getLocalEndpoint(0, null, null);
369:                return localEndpoint.transport;
370:            }
371:
372:            /**
373:             * Returns the current list of known transports.
374:             * The returned list is an unshared collection of Transports,
375:             * including all transports which may have channels to remote
376:             * endpoints.
377:             */
378:            private static Collection<TCPTransport> allKnownTransports() {
379:                // Loop through local endpoints, getting the transport of each one.
380:                Set<TCPTransport> s;
381:                synchronized (localEndpoints) {
382:                    // presize s to number of localEndpoints
383:                    s = new HashSet<TCPTransport>(localEndpoints.size());
384:                    for (LinkedList<TCPEndpoint> epList : localEndpoints
385:                            .values()) {
386:                        /*
387:                         * Each local endpoint has its transport added to s.
388:                         * Note: the transport is the same for all endpoints
389:                         * in the list, so it is okay to pick any one of them.
390:                         */
391:                        TCPEndpoint ep = epList.getFirst();
392:                        s.add(ep.transport);
393:                    }
394:                }
395:                return s;
396:            }
397:
398:            /**
399:             * Release idle outbound connections to reduce demand on I/O resources.
400:             * All transports are asked to release excess connections.
401:             */
402:            public static void shedConnectionCaches() {
403:                for (TCPTransport transport : allKnownTransports()) {
404:                    transport.shedConnectionCaches();
405:                }
406:            }
407:
408:            /**
409:             * Export the object to accept incoming calls.
410:             */
411:            public void exportObject(Target target) throws RemoteException {
412:                transport.exportObject(target);
413:            }
414:
415:            /**
416:             * Returns a channel for this (remote) endpoint.
417:             */
418:            public Channel getChannel() {
419:                return getOutboundTransport().getChannel(this );
420:            }
421:
422:            /**
423:             * Returns address for endpoint
424:             */
425:            public String getHost() {
426:                return host;
427:            }
428:
429:            /**
430:             * Returns the port for this endpoint.  If this endpoint was
431:             * created as a server endpoint (using getLocalEndpoint) for a
432:             * default/anonymous port and its inbound transport has started
433:             * listening, this method returns (instead of zero) the actual
434:             * bound port suitable for passing to clients.
435:             **/
436:            public int getPort() {
437:                return port;
438:            }
439:
440:            /**
441:             * Returns the port that this endpoint's inbound transport listens
442:             * on, if this endpoint was created as a server endpoint (using
443:             * getLocalEndpoint).  If this endpoint was created for the
444:             * default/anonymous port, then this method returns zero even if
445:             * the transport has started listening.
446:             **/
447:            public int getListenPort() {
448:                return listenPort;
449:            }
450:
451:            /**
452:             * Returns the transport for incoming connections to this
453:             * endpoint, if this endpoint was created as a server endpoint
454:             * (using getLocalEndpoint).
455:             **/
456:            public Transport getInboundTransport() {
457:                return transport;
458:            }
459:
460:            /**
461:             * Get the client socket factory associated with this endpoint.
462:             */
463:            public RMIClientSocketFactory getClientSocketFactory() {
464:                return csf;
465:            }
466:
467:            /**
468:             * Get the server socket factory associated with this endpoint.
469:             */
470:            public RMIServerSocketFactory getServerSocketFactory() {
471:                return ssf;
472:            }
473:
474:            /**
475:             * Return string representation for endpoint.
476:             */
477:            public String toString() {
478:                return "[" + host + ":" + port + (ssf != null ? "," + ssf : "")
479:                        + (csf != null ? "," + csf : "") + "]";
480:            }
481:
482:            public int hashCode() {
483:                return port;
484:            }
485:
486:            public boolean equals(Object obj) {
487:                if ((obj != null) && (obj instanceof  TCPEndpoint)) {
488:                    TCPEndpoint ep = (TCPEndpoint) obj;
489:                    if (port != ep.port || !host.equals(ep.host))
490:                        return false;
491:                    if (((csf == null) ^ (ep.csf == null))
492:                            || ((ssf == null) ^ (ep.ssf == null)))
493:                        return false;
494:                    /*
495:                     * Fix for 4254510: perform socket factory *class* equality check
496:                     * before socket factory equality check to avoid passing
497:                     * a potentially naughty socket factory to this endpoint's
498:                     * {client,server} socket factory equals method.
499:                     */
500:                    if ((csf != null)
501:                            && !(csf.getClass() == ep.csf.getClass() && csf
502:                                    .equals(ep.csf)))
503:                        return false;
504:                    if ((ssf != null)
505:                            && !(ssf.getClass() == ep.ssf.getClass() && ssf
506:                                    .equals(ep.ssf)))
507:                        return false;
508:                    return true;
509:                } else {
510:                    return false;
511:                }
512:            }
513:
514:            /* codes for the self-describing formats of wire representation */
515:            private static final int FORMAT_HOST_PORT = 0;
516:            private static final int FORMAT_HOST_PORT_FACTORY = 1;
517:
518:            /**
519:             * Write endpoint to output stream.
520:             */
521:            public void write(ObjectOutput out) throws IOException {
522:                if (csf == null) {
523:                    out.writeByte(FORMAT_HOST_PORT);
524:                    out.writeUTF(host);
525:                    out.writeInt(port);
526:                } else {
527:                    out.writeByte(FORMAT_HOST_PORT_FACTORY);
528:                    out.writeUTF(host);
529:                    out.writeInt(port);
530:                    out.writeObject(csf);
531:                }
532:            }
533:
534:            /**
535:             * Get the endpoint from the input stream.
536:             * @param in the input stream
537:             * @exception IOException If id could not be read (due to stream failure)
538:             */
539:            public static TCPEndpoint read(ObjectInput in) throws IOException,
540:                    ClassNotFoundException {
541:                String host;
542:                int port;
543:                RMIClientSocketFactory csf = null;
544:
545:                byte format = in.readByte();
546:                switch (format) {
547:                case FORMAT_HOST_PORT:
548:                    host = in.readUTF();
549:                    port = in.readInt();
550:                    break;
551:
552:                case FORMAT_HOST_PORT_FACTORY:
553:                    host = in.readUTF();
554:                    port = in.readInt();
555:                    csf = (RMIClientSocketFactory) in.readObject();
556:                    break;
557:
558:                default:
559:                    throw new IOException("invalid endpoint format");
560:                }
561:                return new TCPEndpoint(host, port, csf, null);
562:            }
563:
564:            /**
565:             * Write endpoint to output stream in older format used by
566:             * UnicastRef for JDK1.1 compatibility.
567:             */
568:            public void writeHostPortFormat(DataOutput out) throws IOException {
569:                if (csf != null) {
570:                    throw new InternalError(
571:                            "TCPEndpoint.writeHostPortFormat: "
572:                                    + "called for endpoint with non-null socket factory");
573:                }
574:                out.writeUTF(host);
575:                out.writeInt(port);
576:            }
577:
578:            /**
579:             * Create a new endpoint from input stream data.
580:             * @param in the input stream
581:             */
582:            public static TCPEndpoint readHostPortFormat(DataInput in)
583:                    throws IOException {
584:                String host = in.readUTF();
585:                int port = in.readInt();
586:                return new TCPEndpoint(host, port);
587:            }
588:
589:            private static RMISocketFactory chooseFactory() {
590:                RMISocketFactory sf = RMISocketFactory.getSocketFactory();
591:                if (sf == null) {
592:                    sf = TCPTransport.defaultSocketFactory;
593:                }
594:                return sf;
595:            }
596:
597:            /**
598:             * Open and return new client socket connection to endpoint.
599:             */
600:            Socket newSocket() throws RemoteException {
601:                if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
602:                    TCPTransport.tcpLog.log(Log.VERBOSE, "opening socket to "
603:                            + this );
604:                }
605:
606:                Socket socket;
607:
608:                try {
609:                    RMIClientSocketFactory clientFactory = csf;
610:                    if (clientFactory == null) {
611:                        clientFactory = chooseFactory();
612:                    }
613:                    socket = clientFactory.createSocket(host, port);
614:
615:                } catch (java.net.UnknownHostException e) {
616:                    throw new java.rmi.UnknownHostException("Unknown host: "
617:                            + host, e);
618:                } catch (java.net.ConnectException e) {
619:                    throw new java.rmi.ConnectException(
620:                            "Connection refused to host: " + host, e);
621:                } catch (IOException e) {
622:                    // We might have simply run out of file descriptors
623:                    try {
624:                        TCPEndpoint.shedConnectionCaches();
625:                        // REMIND: should we retry createSocket?
626:                    } catch (OutOfMemoryError mem) {
627:                        // don't quit if out of memory
628:                    } catch (Exception ex) {
629:                        // don't quit if shed fails non-catastrophically
630:                    }
631:
632:                    throw new ConnectIOException(
633:                            "Exception creating connection to: " + host, e);
634:                }
635:
636:                // set socket to disable Nagle's algorithm (always send immediately)
637:                // TBD: should this be left up to socket factory instead?
638:                try {
639:                    socket.setTcpNoDelay(true);
640:                } catch (Exception e) {
641:                    // if we fail to set this, ignore and proceed anyway
642:                }
643:
644:                // fix 4187495: explicitly set SO_KEEPALIVE to prevent client hangs
645:                try {
646:                    socket.setKeepAlive(true);
647:                } catch (Exception e) {
648:                    // ignore and proceed
649:                }
650:
651:                return socket;
652:            }
653:
654:            /**
655:             * Return new server socket to listen for connections on this endpoint.
656:             */
657:            ServerSocket newServerSocket() throws IOException {
658:                if (TCPTransport.tcpLog.isLoggable(Log.VERBOSE)) {
659:                    TCPTransport.tcpLog.log(Log.VERBOSE,
660:                            "creating server socket on " + this );
661:                }
662:
663:                RMIServerSocketFactory serverFactory = ssf;
664:                if (serverFactory == null) {
665:                    serverFactory = chooseFactory();
666:                }
667:                ServerSocket server = serverFactory
668:                        .createServerSocket(listenPort);
669:
670:                // if we listened on an anonymous port, set the default port
671:                // (for this socket factory)
672:                if (listenPort == 0)
673:                    setDefaultPort(server.getLocalPort(), csf, ssf);
674:
675:                return server;
676:            }
677:
678:            /**
679:             * The class FQDN encapsulates a routine that makes a best effort
680:             * attempt to retrieve the fully qualified domain name of the local
681:             * host.
682:             *
683:             * @author 	Laird Dornin
684:             */
685:            private static class FQDN implements  Runnable {
686:
687:                /**
688:                 * strings in which we can store discovered fqdn
689:                 */
690:                private String reverseLookup;
691:
692:                private String hostAddress;
693:
694:                private FQDN(String hostAddress) {
695:                    this .hostAddress = hostAddress;
696:                }
697:
698:                /**
699:                 * Do our best to obtain a fully qualified hostname for the local
700:                 * host.  Perform the following steps to get a localhostname:
701:                 * 
702:                 * 1. InetAddress.getLocalHost().getHostName() - if contains
703:                 *    '.' use as FQDN
704:                 * 2. if no '.' query name service for FQDN in a thread
705:                 *    Note: We query the name service for an FQDN by creating 
706:                 *    an InetAddress via a stringified copy of the local ip 
707:                 *    address; this creates an InetAddress with a null hostname.
708:                 *    Asking for the hostname of this InetAddress causes a name
709:                 *    service lookup.
710:                 *
711:                 * 3. if name service takes too long to return, use ip address
712:                 * 4. if name service returns but response contains no '.' 
713:                 *    default to ipaddress.
714:                 */
715:                static String attemptFQDN(InetAddress localAddr)
716:                        throws java.net.UnknownHostException {
717:
718:                    String hostName = localAddr.getHostName();
719:
720:                    if (hostName.indexOf('.') < 0) {
721:
722:                        String hostAddress = localAddr.getHostAddress();
723:                        FQDN f = new FQDN(hostAddress);
724:
725:                        int nameServiceTimeOut = TCPEndpoint.getInt(
726:                                "sun.rmi.transport.tcp.localHostNameTimeOut",
727:                                10000);
728:
729:                        try {
730:                            synchronized (f) {
731:                                f.getFQDN();
732:
733:                                /* wait to obtain an FQDN */
734:                                f.wait(nameServiceTimeOut);
735:                            }
736:                        } catch (InterruptedException e) {
737:                            /* propagate the exception to the caller */
738:                            Thread.currentThread().interrupt();
739:                        }
740:                        hostName = f.getHost();
741:
742:                        if ((hostName == null) || (hostName.equals(""))
743:                                || (hostName.indexOf('.') < 0)) {
744:
745:                            hostName = hostAddress;
746:                        }
747:                    }
748:                    return hostName;
749:                }
750:
751:                /** 
752:                 * Method that that will start a thread to wait to retrieve a
753:                 * fully qualified domain name from a name service.  The spawned
754:                 * thread may never return but we have marked it as a daemon so the vm
755:                 * will terminate appropriately.  
756:                 */
757:                private void getFQDN() {
758:
759:                    /* FQDN finder will run in RMI threadgroup. */
760:                    Thread t = AccessController
761:                            .doPrivileged(new NewThreadAction(FQDN.this ,
762:                                    "FQDN Finder", true));
763:                    t.start();
764:                }
765:
766:                private synchronized String getHost() {
767:                    return reverseLookup;
768:                }
769:
770:                /**
771:                 * thread to query a name service for the fqdn of this host.
772:                 */
773:                public void run() {
774:
775:                    String name = null;
776:
777:                    try {
778:                        name = InetAddress.getByName(hostAddress).getHostName();
779:                    } catch (java.net.UnknownHostException e) {
780:                    } finally {
781:                        synchronized (this) {
782:                            reverseLookup = name;
783:                            this.notify();
784:                        }
785:                    }
786:                }
787:            }
788:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.