Source Code Cross Referenced for PlainSocketImpl.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » luni » net » 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 » Apache Harmony Java SE » org package » org.apache.harmony.luni.net 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
003:         *  contributor license agreements.  See the NOTICE file distributed with
004:         *  this work for additional information regarding copyright ownership.
005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
006:         *  (the "License"); you may not use this file except in compliance with
007:         *  the License.  You may obtain a copy of the License at
008:         *
009:         *     http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         *  Unless required by applicable law or agreed to in writing, software
012:         *  distributed under the License is distributed on an "AS IS" BASIS,
013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         *  See the License for the specific language governing permissions and
015:         *  limitations under the License.
016:         */
017:
018:        package org.apache.harmony.luni.net;
019:
020:        import java.io.FileDescriptor;
021:        import java.io.IOException;
022:        import java.io.InputStream;
023:        import java.io.InterruptedIOException;
024:        import java.io.OutputStream;
025:        import java.lang.reflect.Field;
026:        import java.net.ConnectException;
027:        import java.net.InetAddress;
028:        import java.net.InetSocketAddress;
029:        import java.net.Proxy;
030:        import java.net.SocketAddress;
031:        import java.net.SocketException;
032:        import java.net.SocketImpl;
033:        import java.net.SocketOptions;
034:        import java.net.SocketTimeoutException;
035:        import java.net.UnknownHostException;
036:        import java.security.AccessController;
037:        import java.security.PrivilegedAction;
038:
039:        import org.apache.harmony.luni.platform.INetworkSystem;
040:        import org.apache.harmony.luni.platform.Platform;
041:        import org.apache.harmony.luni.util.Msg;
042:
043:        /**
044:         * A concrete connected-socket implementation.
045:         */
046:        class PlainSocketImpl extends SocketImpl {
047:
048:            // Const copy from socket
049:
050:            static final int MULTICAST_IF = 1;
051:
052:            static final int MULTICAST_TTL = 2;
053:
054:            static final int TCP_NODELAY = 4;
055:
056:            static final int FLAG_SHUTDOWN = 8;
057:
058:            // For SOCKS support. A SOCKS bind() uses the last
059:            // host connected to in its request.
060:            static private InetAddress lastConnectedAddress;
061:
062:            static private int lastConnectedPort;
063:
064:            private static Field fdField;
065:
066:            private static Field localportField;
067:
068:            private boolean tcpNoDelay = true;
069:
070:            /**
071:             * used to store the trafficClass value which is simply returned as the
072:             * value that was set. We also need it to pass it to methods that specify an
073:             * address packets are going to be sent to
074:             */
075:            private int trafficClass;
076:
077:            protected INetworkSystem netImpl = Platform.getNetworkSystem();
078:
079:            public int receiveTimeout = 0;
080:
081:            public boolean streaming = true;
082:
083:            public boolean shutdownInput;
084:
085:            Proxy proxy;
086:
087:            public PlainSocketImpl() {
088:                super ();
089:                fd = new FileDescriptor();
090:            }
091:
092:            @Override
093:            protected void accept(SocketImpl newImpl) throws IOException {
094:                if (NetUtil.usingSocks(proxy)) {
095:                    ((PlainSocketImpl) newImpl).socksBind();
096:                    ((PlainSocketImpl) newImpl).socksAccept();
097:                    return;
098:                }
099:
100:                try {
101:                    if (newImpl instanceof  PlainSocketImpl) {
102:                        PlainSocketImpl newPlainSocketImpl = (PlainSocketImpl) newImpl;
103:                        netImpl.acceptStreamSocket(fd, newImpl,
104:                                newPlainSocketImpl.getFileDescriptor(),
105:                                receiveTimeout);
106:                        newPlainSocketImpl.setLocalport(getLocalPort());
107:                    } else {
108:                        // if newImpl is not an instance of PlainSocketImpl, use
109:                        // reflection to get/set protected fields.
110:                        if (null == fdField) {
111:                            fdField = getSocketImplField("fd"); //$NON-NLS-1$
112:                        }
113:                        FileDescriptor newFd = (FileDescriptor) fdField
114:                                .get(newImpl);
115:                        netImpl.acceptStreamSocket(fd, newImpl, newFd,
116:                                receiveTimeout);
117:
118:                        if (null == localportField) {
119:                            localportField = getSocketImplField("localport"); //$NON-NLS-1$
120:                        }
121:                        localportField.setInt(newImpl, getLocalPort());
122:                    }
123:                } catch (InterruptedIOException e) {
124:                    throw new SocketTimeoutException(e.getMessage());
125:                } catch (IllegalAccessException e) {
126:                    // empty
127:                }
128:            }
129:
130:            /**
131:             * gets SocketImpl field by reflection.
132:             */
133:            private Field getSocketImplField(final String fieldName) {
134:                return AccessController
135:                        .doPrivileged(new PrivilegedAction<Field>() {
136:                            public Field run() {
137:                                Field field = null;
138:                                try {
139:                                    field = SocketImpl.class
140:                                            .getDeclaredField(fieldName);
141:                                    field.setAccessible(true);
142:                                } catch (NoSuchFieldException e) {
143:                                    throw new Error(e);
144:                                }
145:                                return field;
146:                            }
147:                        });
148:            }
149:
150:            @Override
151:            protected synchronized int available() throws IOException {
152:                // we need to check if the input has been shutdown. If so
153:                // we should return that there is no data to be read
154:                if (shutdownInput == true) {
155:                    return 0;
156:                }
157:                return netImpl.availableStream(fd);
158:            }
159:
160:            @Override
161:            protected void bind(InetAddress anAddr, int aPort)
162:                    throws IOException {
163:                netImpl.bind(fd, aPort, anAddr);
164:                // PlainSocketImpl2.socketBindImpl2(fd, aPort, anAddr);
165:                address = anAddr;
166:                if (0 != aPort) {
167:                    localport = aPort;
168:                } else {
169:                    localport = netImpl.getSocketLocalPort(fd, NetUtil
170:                            .preferIPv6Addresses());
171:                }
172:            }
173:
174:            @Override
175:            protected void close() throws IOException {
176:                synchronized (fd) {
177:                    if (fd.valid()) {
178:                        if ((netImpl.getSocketFlags() & FLAG_SHUTDOWN) != 0) {
179:                            try {
180:                                shutdownOutput();
181:                            } catch (Exception e) {
182:                            }
183:                        }
184:                        netImpl.socketClose(fd);
185:                        fd = new FileDescriptor();
186:                    }
187:                }
188:            }
189:
190:            @Override
191:            protected void connect(String aHost, int aPort) throws IOException {
192:                InetAddress anAddr = netImpl.getHostByName(aHost, NetUtil
193:                        .preferIPv6Addresses());
194:                connect(anAddr, aPort);
195:            }
196:
197:            @Override
198:            protected void connect(InetAddress anAddr, int aPort)
199:                    throws IOException {
200:                connect(anAddr, aPort, 0);
201:            }
202:
203:            /**
204:             * Connects this socket to the specified remote host address/port.
205:             * 
206:             * @param anAddr
207:             *            the remote host address to connect to
208:             * @param aPort
209:             *            the remote port to connect to
210:             * @param timeout
211:             *            a timeout where supported. 0 means no timeout
212:             * @throws IOException
213:             *             if an error occurs while connecting
214:             */
215:            private void connect(InetAddress anAddr, int aPort, int timeout)
216:                    throws IOException {
217:                InetAddress normalAddr = anAddr.isAnyLocalAddress() ? InetAddress
218:                        .getLocalHost()
219:                        : anAddr;
220:
221:                try {
222:                    if (streaming) {
223:                        if (NetUtil.usingSocks(proxy)) {
224:                            socksConnect(anAddr, aPort, 0);
225:                        } else {
226:                            if (timeout == 0) {
227:                                netImpl.connect(fd, trafficClass, normalAddr,
228:                                        aPort);
229:                            } else {
230:                                netImpl.connectStreamWithTimeoutSocket(fd,
231:                                        aPort, timeout, trafficClass,
232:                                        normalAddr);
233:                            }
234:                        }
235:                    } else {
236:                        netImpl.connectDatagram(fd, aPort, trafficClass,
237:                                normalAddr);
238:                    }
239:                } catch (ConnectException e) {
240:                    throw new ConnectException(anAddr + ":" + aPort + " - "
241:                            + e.getMessage());
242:                }
243:                super .address = normalAddr;
244:                super .port = aPort;
245:            }
246:
247:            @Override
248:            protected void create(boolean streaming) throws IOException {
249:                this .streaming = streaming;
250:                if (streaming) {
251:                    netImpl.createStreamSocket(fd, NetUtil.preferIPv4Stack());
252:                } else {
253:                    netImpl.createDatagramSocket(fd, NetUtil.preferIPv4Stack());
254:                }
255:            }
256:
257:            @Override
258:            protected void finalize() throws IOException {
259:                close();
260:            }
261:
262:            @Override
263:            protected synchronized InputStream getInputStream()
264:                    throws IOException {
265:                if (!fd.valid()) {
266:                    throw new SocketException(Msg.getString("K003d"));
267:                }
268:
269:                return new SocketInputStream(this );
270:            }
271:
272:            @Override
273:            public Object getOption(int optID) throws SocketException {
274:                if (optID == SocketOptions.SO_TIMEOUT) {
275:                    return Integer.valueOf(receiveTimeout);
276:                } else if (optID == SocketOptions.IP_TOS) {
277:                    return Integer.valueOf(trafficClass);
278:                } else {
279:                    // Call the native first so there will be
280:                    // an exception if the socket if closed.
281:                    Object result = netImpl.getSocketOption(fd, optID);
282:                    if (optID == SocketOptions.TCP_NODELAY
283:                            && (netImpl.getSocketFlags() & TCP_NODELAY) != 0) {
284:                        return Boolean.valueOf(tcpNoDelay);
285:                    }
286:                    return result;
287:                }
288:            }
289:
290:            @Override
291:            protected synchronized OutputStream getOutputStream()
292:                    throws IOException {
293:                if (!fd.valid()) {
294:                    throw new SocketException(Msg.getString("K003d")); //$NON-NLS-1$
295:                }
296:                return new SocketOutputStream(this );
297:            }
298:
299:            @Override
300:            protected void listen(int backlog) throws IOException {
301:                if (NetUtil.usingSocks(proxy)) {
302:                    // Do nothing for a SOCKS connection. The listen occurs on the
303:                    // server during the bind.
304:                    return;
305:                }
306:                netImpl.listenStreamSocket(fd, backlog);
307:            }
308:
309:            @Override
310:            public void setOption(int optID, Object val) throws SocketException {
311:                if (optID == SocketOptions.SO_TIMEOUT) {
312:                    receiveTimeout = ((Integer) val).intValue();
313:                } else {
314:                    try {
315:                        netImpl.setSocketOption(fd, optID, val);
316:                        if (optID == SocketOptions.TCP_NODELAY
317:                                && (netImpl.getSocketFlags() & TCP_NODELAY) != 0) {
318:                            tcpNoDelay = ((Boolean) val).booleanValue();
319:                        }
320:                    } catch (SocketException e) {
321:                        // we don't throw an exception for IP_TOS even if the platform
322:                        // won't let us set the requested value
323:                        if (optID != SocketOptions.IP_TOS) {
324:                            throw e;
325:                        }
326:                    }
327:
328:                    /*
329:                     * save this value as it is actually used differently for IPv4 and
330:                     * IPv6 so we cannot get the value using the getOption. The option
331:                     * is actually only set for IPv4 and a masked version of the value
332:                     * will be set as only a subset of the values are allowed on the
333:                     * socket. Therefore we need to retain it to return the value that
334:                     * was set. We also need the value to be passed into a number of
335:                     * natives so that it can be used properly with IPv6
336:                     */
337:                    if (optID == SocketOptions.IP_TOS) {
338:                        trafficClass = ((Integer) val).intValue();
339:                    }
340:                }
341:            }
342:
343:            /**
344:             * Gets the SOCKS proxy server port.
345:             */
346:            private int socksGetServerPort() {
347:                // get socks server port from proxy. It is unnecessary to check
348:                // "socksProxyPort" property, since proxy setting should only be
349:                // determined by ProxySelector.
350:                InetSocketAddress addr = (InetSocketAddress) proxy.address();
351:                return addr.getPort();
352:
353:            }
354:
355:            /**
356:             * Gets the InetAddress of the SOCKS proxy server.
357:             */
358:            private InetAddress socksGetServerAddress()
359:                    throws UnknownHostException {
360:                String proxyName;
361:                // get socks server address from proxy. It is unnecessary to check
362:                // "socksProxyHost" property, since all proxy setting should be
363:                // determined by ProxySelector.
364:                InetSocketAddress addr = (InetSocketAddress) proxy.address();
365:                proxyName = addr.getHostName();
366:                if (null == proxyName) {
367:                    proxyName = addr.getAddress().getHostAddress();
368:                }
369:
370:                InetAddress anAddr = netImpl.getHostByName(proxyName, NetUtil
371:                        .preferIPv6Addresses());
372:                return anAddr;
373:            }
374:
375:            /**
376:             * Connect using a SOCKS server.
377:             */
378:            private void socksConnect(InetAddress applicationServerAddress,
379:                    int applicationServerPort, int timeout) throws IOException {
380:                try {
381:                    if (timeout == 0) {
382:                        netImpl.connect(fd, trafficClass,
383:                                socksGetServerAddress(), socksGetServerPort());
384:                    } else {
385:                        netImpl.connectStreamWithTimeoutSocket(fd,
386:                                socksGetServerPort(), timeout, trafficClass,
387:                                socksGetServerAddress());
388:                    }
389:
390:                } catch (Exception e) {
391:                    throw new SocketException(Msg.getString("K003e", e)); //$NON-NLS-1$
392:                }
393:
394:                socksRequestConnection(applicationServerAddress,
395:                        applicationServerPort);
396:
397:                lastConnectedAddress = applicationServerAddress;
398:                lastConnectedPort = applicationServerPort;
399:            }
400:
401:            /**
402:             * Request a SOCKS connection to the application server given. If the
403:             * request fails to complete successfully, an exception is thrown.
404:             */
405:            private void socksRequestConnection(
406:                    InetAddress applicationServerAddress,
407:                    int applicationServerPort) throws IOException {
408:                socksSendRequest(Socks4Message.COMMAND_CONNECT,
409:                        applicationServerAddress, applicationServerPort);
410:                Socks4Message reply = socksReadReply();
411:                if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) {
412:                    throw new IOException(reply.getErrorString(reply
413:                            .getCommandOrResult()));
414:                }
415:            }
416:
417:            /**
418:             * Perform an accept for a SOCKS bind.
419:             */
420:            public void socksAccept() throws IOException {
421:                Socks4Message reply = socksReadReply();
422:                if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) {
423:                    throw new IOException(reply.getErrorString(reply
424:                            .getCommandOrResult()));
425:                }
426:            }
427:
428:            /**
429:             * Shutdown the input portion of the socket.
430:             */
431:            @Override
432:            protected void shutdownInput() throws IOException {
433:                shutdownInput = true;
434:                netImpl.shutdownInput(fd);
435:            }
436:
437:            /**
438:             * Shutdown the output portion of the socket.
439:             */
440:            @Override
441:            protected void shutdownOutput() throws IOException {
442:                netImpl.shutdownOutput(fd);
443:            }
444:
445:            /**
446:             * Bind using a SOCKS server.
447:             */
448:            private void socksBind() throws IOException {
449:                try {
450:                    netImpl.connect(fd, trafficClass, socksGetServerAddress(),
451:                            socksGetServerPort());
452:                } catch (Exception e) {
453:                    throw new IOException(Msg.getString("K003f", e)); //$NON-NLS-1$
454:                }
455:
456:                // There must be a connection to an application host for the bind to
457:                // work.
458:                if (lastConnectedAddress == null) {
459:                    throw new SocketException(Msg.getString("K0040")); //$NON-NLS-1$
460:                }
461:
462:                // Use the last connected address and port in the bind request.
463:                socksSendRequest(Socks4Message.COMMAND_BIND,
464:                        lastConnectedAddress, lastConnectedPort);
465:                Socks4Message reply = socksReadReply();
466:
467:                if (reply.getCommandOrResult() != Socks4Message.RETURN_SUCCESS) {
468:                    throw new IOException(reply.getErrorString(reply
469:                            .getCommandOrResult()));
470:                }
471:
472:                // A peculiarity of socks 4 - if the address returned is 0, use the
473:                // original socks server address.
474:                if (reply.getIP() == 0) {
475:                    address = socksGetServerAddress();
476:                } else {
477:                    // IPv6 support not yet required as
478:                    // currently the Socks4Message.getIP() only returns int,
479:                    // so only works with IPv4 4byte addresses
480:                    byte[] replyBytes = new byte[4];
481:                    NetUtil.intToBytes(reply.getIP(), replyBytes, 0);
482:                    address = InetAddress.getByAddress(replyBytes);
483:                }
484:                localport = reply.getPort();
485:            }
486:
487:            /**
488:             * Send a SOCKS V4 request.
489:             */
490:            private void socksSendRequest(int command, InetAddress address,
491:                    int port) throws IOException {
492:                Socks4Message request = new Socks4Message();
493:                request.setCommandOrResult(command);
494:                request.setPort(port);
495:                request.setIP(address.getAddress());
496:                request.setUserId("default"); //$NON-NLS-1$
497:
498:                getOutputStream().write(request.getBytes(), 0,
499:                        request.getLength());
500:            }
501:
502:            /**
503:             * Read a SOCKS V4 reply.
504:             */
505:            private Socks4Message socksReadReply() throws IOException {
506:                Socks4Message reply = new Socks4Message();
507:                int bytesRead = 0;
508:                while (bytesRead < Socks4Message.REPLY_LENGTH) {
509:                    int count = getInputStream().read(reply.getBytes(),
510:                            bytesRead, Socks4Message.REPLY_LENGTH - bytesRead);
511:                    if (-1 == count) {
512:                        break;
513:                    }
514:                    bytesRead += count;
515:                }
516:                if (Socks4Message.REPLY_LENGTH != bytesRead) {
517:                    throw new SocketException(Msg.getString("KA011")); //$NON-NLS-1$
518:                }
519:                return reply;
520:            }
521:
522:            @Override
523:            protected void connect(SocketAddress remoteAddr, int timeout)
524:                    throws IOException {
525:                InetSocketAddress inetAddr = (InetSocketAddress) remoteAddr;
526:                connect(inetAddr.getAddress(), inetAddr.getPort(), timeout);
527:            }
528:
529:            /**
530:             * Answer if the socket supports urgent data.
531:             */
532:            @Override
533:            protected boolean supportsUrgentData() {
534:                return !streaming || netImpl.supportsUrgentData(fd);
535:            }
536:
537:            @Override
538:            protected void sendUrgentData(int value) throws IOException {
539:                netImpl.sendUrgentData(fd, (byte) value);
540:            }
541:
542:            FileDescriptor getFD() {
543:                return fd;
544:            }
545:
546:            private void setLocalport(int localport) {
547:                this .localport = localport;
548:            }
549:
550:            int read(byte[] buffer, int offset, int count) throws IOException {
551:                if (shutdownInput) {
552:                    return -1;
553:                }
554:                try {
555:                    int read = netImpl.receiveStream(fd, buffer, offset, count,
556:                            receiveTimeout);
557:                    if (read == -1) {
558:                        shutdownInput = true;
559:                    }
560:                    return read;
561:                } catch (InterruptedIOException e) {
562:                    throw new SocketTimeoutException(e.getMessage());
563:                }
564:            }
565:
566:            int write(byte[] buffer, int offset, int count) throws IOException {
567:                if (!streaming) {
568:                    return netImpl.sendDatagram2(fd, buffer, offset, count,
569:                            port, address);
570:                }
571:                return netImpl.sendStream(fd, buffer, offset, count);
572:            }
573:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.