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


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         */
0017:
0018:        package org.apache.harmony.nio.internal;
0019:
0020:        import java.io.FileDescriptor;
0021:        import java.io.IOException;
0022:        import java.io.InputStream;
0023:        import java.io.OutputStream;
0024:        import java.net.ConnectException;
0025:        import java.net.InetAddress;
0026:        import java.net.InetSocketAddress;
0027:        import java.net.Socket;
0028:        import java.net.SocketAddress;
0029:        import java.net.SocketException;
0030:        import java.net.SocketImpl;
0031:        import java.net.SocketOptions;
0032:        import java.net.UnknownHostException;
0033:        import java.nio.ByteBuffer;
0034:        import java.nio.channels.AlreadyConnectedException;
0035:        import java.nio.channels.ClosedChannelException;
0036:        import java.nio.channels.ConnectionPendingException;
0037:        import java.nio.channels.IllegalBlockingModeException;
0038:        import java.nio.channels.NoConnectionPendingException;
0039:        import java.nio.channels.NotYetConnectedException;
0040:        import java.nio.channels.SocketChannel;
0041:        import java.nio.channels.UnresolvedAddressException;
0042:        import java.nio.channels.UnsupportedAddressTypeException;
0043:        import java.nio.channels.spi.SelectorProvider;
0044:
0045:        import org.apache.harmony.luni.net.SocketImplProvider;
0046:        import org.apache.harmony.luni.platform.FileDescriptorHandler;
0047:        import org.apache.harmony.luni.platform.INetworkSystem;
0048:        import org.apache.harmony.luni.platform.Platform;
0049:        import org.apache.harmony.luni.util.ErrorCodeException;
0050:        import org.apache.harmony.nio.AddressUtil;
0051:        import org.apache.harmony.nio.internal.nls.Messages;
0052:
0053:        /*
0054:         * The default implementation class of java.nio.channels.SocketChannel.
0055:         */
0056:        class SocketChannelImpl extends SocketChannel implements 
0057:                FileDescriptorHandler {
0058:
0059:            private static final int EOF = -1;
0060:
0061:            private static final int ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK = -211;
0062:
0063:            // The singleton to do the native network operation.
0064:            static final INetworkSystem networkSystem = Platform
0065:                    .getNetworkSystem();
0066:
0067:            // Status un-init, not initialized.
0068:            static final int SOCKET_STATUS_UNINIT = EOF;
0069:
0070:            // Status before connect.
0071:            static final int SOCKET_STATUS_UNCONNECTED = 0;
0072:
0073:            // Status connection pending.
0074:            static final int SOCKET_STATUS_PENDING = 1;
0075:
0076:            // Status after connection success.
0077:            static final int SOCKET_STATUS_CONNECTED = 2;
0078:
0079:            // Status closed.
0080:            static final int SOCKET_STATUS_CLOSED = 3;
0081:
0082:            // Timeout used for non-block mode.
0083:            private static final int TIMEOUT_NONBLOCK = 0;
0084:
0085:            // Timeout used for block mode.
0086:            private static final int TIMEOUT_BLOCK = EOF;
0087:
0088:            // Step used for connect.
0089:            private static final int HY_SOCK_STEP_START = 0;
0090:
0091:            // Step used for finishConnect.
0092:            private static final int HY_PORT_SOCKET_STEP_CHECK = 1;
0093:
0094:            // Connect success.
0095:            private static final int CONNECT_SUCCESS = 0;
0096:
0097:            // The descriptor to interact with native code.
0098:            FileDescriptor fd;
0099:
0100:            // Our internal Socket.
0101:            private Socket socket = null;
0102:
0103:            // The address to be connected.
0104:            InetSocketAddress connectAddress = null;
0105:
0106:            // Local address of the this socket (package private for adapter).
0107:            InetAddress localAddress = null;
0108:
0109:            // Local port number.
0110:            int localPort;
0111:
0112:            // At first, uninitialized.
0113:            int status = SOCKET_STATUS_UNINIT;
0114:
0115:            // Whether the socket is bound.
0116:            volatile boolean isBound = false;
0117:
0118:            private static class ReadLock {
0119:            }
0120:
0121:            private final Object readLock = new ReadLock();
0122:
0123:            private static class WriteLock {
0124:            }
0125:
0126:            private final Object writeLock = new WriteLock();
0127:
0128:            // This content is a point used to set in connect_withtimeout() in pending
0129:            // mode.
0130:            private Long connectContext = Long.valueOf(0L);
0131:
0132:            // Used to store the trafficClass value which is simply returned
0133:            // as the value that was set. We also need it to pass it to methods
0134:            // that specify an address packets are going to be sent to.
0135:            private int trafficClass = 0;
0136:
0137:            /*
0138:             * Constructor for creating a connected socket channel.
0139:             */
0140:            public SocketChannelImpl(SelectorProvider selectorProvider)
0141:                    throws IOException {
0142:                this (selectorProvider, true);
0143:            }
0144:
0145:            /*
0146:             * Constructor for creating an optionally connected socket channel.
0147:             */
0148:            public SocketChannelImpl(SelectorProvider selectorProvider,
0149:                    boolean connect) throws IOException {
0150:                super (selectorProvider);
0151:                fd = new FileDescriptor();
0152:                status = SOCKET_STATUS_UNCONNECTED;
0153:                if (connect) {
0154:                    networkSystem.createSocket(fd, true);
0155:                }
0156:            }
0157:
0158:            /*
0159:             * For native call.
0160:             */
0161:            @SuppressWarnings("unused")
0162:            private SocketChannelImpl() {
0163:                super (SelectorProvider.provider());
0164:                fd = new FileDescriptor();
0165:                connectAddress = new InetSocketAddress(0);
0166:                status = SOCKET_STATUS_CONNECTED;
0167:            }
0168:
0169:            // Keep this to see if need next version
0170:            // SocketChannelImpl(SelectorProvider selectorProvider, FileDescriptor fd,
0171:            // SocketImpl si) {
0172:            // super(selectorProvider);
0173:            // fd = fd;
0174:            // networkSystem = OSNetworkSystem.getOSNetworkSystem();
0175:            // status = SOCKET_STATUS_UNCONNECTED;
0176:            // networkSystem.createSocket(fd, true);
0177:            // }
0178:
0179:            /*
0180:             * Package private constructor.
0181:             */
0182:            SocketChannelImpl(Socket aSocket, FileDescriptor aFd) {
0183:                super (SelectorProvider.provider());
0184:                socket = aSocket;
0185:                fd = aFd;
0186:                status = SOCKET_STATUS_UNCONNECTED;
0187:            }
0188:
0189:            /*
0190:             * Getting the internal Socket If we have not the socket, we create a new
0191:             * one.
0192:             */
0193:            @Override
0194:            synchronized public Socket socket() {
0195:                if (null == socket) {
0196:                    try {
0197:                        InetAddress addr = null;
0198:                        int port = 0;
0199:                        if (connectAddress != null) {
0200:                            addr = connectAddress.getAddress();
0201:                            port = connectAddress.getPort();
0202:                        }
0203:                        socket = new SocketAdapter(SocketImplProvider
0204:                                .getSocketImpl(fd, localPort, addr, port), this );
0205:                    } catch (SocketException e) {
0206:                        return null;
0207:                    }
0208:                }
0209:                return socket;
0210:            }
0211:
0212:            /**
0213:             * @see java.nio.channels.SocketChannel#isConnected()
0214:             */
0215:            @Override
0216:            synchronized public boolean isConnected() {
0217:                return status == SOCKET_STATUS_CONNECTED;
0218:            }
0219:
0220:            /*
0221:             * Status setting used by other class.
0222:             */
0223:            synchronized void setConnected() {
0224:                status = SOCKET_STATUS_CONNECTED;
0225:            }
0226:
0227:            void setBound(boolean flag) {
0228:                isBound = flag;
0229:            }
0230:
0231:            /**
0232:             * @see java.nio.channels.SocketChannel#isConnectionPending()
0233:             */
0234:            @Override
0235:            synchronized public boolean isConnectionPending() {
0236:                return status == SOCKET_STATUS_PENDING;
0237:            }
0238:
0239:            /**
0240:             * @see java.nio.channels.SocketChannel#connect(java.net.SocketAddress)
0241:             */
0242:            @Override
0243:            public boolean connect(SocketAddress socketAddress)
0244:                    throws IOException {
0245:                // status must be open and unconnected
0246:                checkUnconnected();
0247:
0248:                // check the address
0249:                InetSocketAddress inetSocketAddress = validateAddress(socketAddress);
0250:
0251:                int port = inetSocketAddress.getPort();
0252:                String hostName = inetSocketAddress.getAddress().getHostName();
0253:                // security check
0254:                SecurityManager sm = System.getSecurityManager();
0255:                if (sm != null) {
0256:                    sm.checkConnect(hostName, port);
0257:                }
0258:
0259:                // connect result
0260:                int result = EOF;
0261:                boolean finished = false;
0262:
0263:                try {
0264:                    if (!isBound) {
0265:                        // bind
0266:                        networkSystem.bind2(fd, 0, true, InetAddress
0267:                                .getByAddress(new byte[] { 0, 0, 0, 0 }));
0268:                        isBound = true;
0269:                    }
0270:
0271:                    if (isBlocking()) {
0272:                        begin();
0273:                        result = networkSystem.connect(fd, trafficClass,
0274:                                inetSocketAddress.getAddress(),
0275:                                inetSocketAddress.getPort());
0276:
0277:                    } else {
0278:                        result = networkSystem.connectWithTimeout(fd, 0,
0279:                                trafficClass, inetSocketAddress.getAddress(),
0280:                                inetSocketAddress.getPort(),
0281:                                HY_SOCK_STEP_START, connectContext);
0282:                        // set back to nonblocking to work around with a bug in portlib
0283:                        if (!this .isBlocking()) {
0284:                            networkSystem.setNonBlocking(fd, true);
0285:                        }
0286:                    }
0287:                    finished = (CONNECT_SUCCESS == result);
0288:                    isBound = finished;
0289:                } catch (IOException e) {
0290:                    if (e instanceof  ConnectException && !isBlocking()) {
0291:                        status = SOCKET_STATUS_PENDING;
0292:                    } else {
0293:                        if (isOpen()) {
0294:                            close();
0295:                            finished = true;
0296:                        }
0297:                        throw e;
0298:                    }
0299:                } finally {
0300:                    if (isBlocking()) {
0301:                        end(finished);
0302:                    }
0303:                }
0304:
0305:                // set local port
0306:                localPort = networkSystem.getSocketLocalPort(fd, false);
0307:                localAddress = networkSystem.getSocketLocalAddress(fd, false);
0308:
0309:                // set the connected address.
0310:                connectAddress = inetSocketAddress;
0311:                synchronized (this ) {
0312:                    if (isBlocking()) {
0313:                        status = (finished ? SOCKET_STATUS_CONNECTED
0314:                                : SOCKET_STATUS_UNCONNECTED);
0315:                    } else {
0316:                        status = SOCKET_STATUS_PENDING;
0317:                    }
0318:                }
0319:                return finished;
0320:            }
0321:
0322:            /**
0323:             * @see java.nio.channels.SocketChannel#finishConnect()
0324:             */
0325:            @Override
0326:            public boolean finishConnect() throws IOException {
0327:                // status check
0328:                synchronized (this ) {
0329:                    if (!isOpen()) {
0330:                        throw new ClosedChannelException();
0331:                    }
0332:                    if (status == SOCKET_STATUS_CONNECTED) {
0333:                        return true;
0334:                    }
0335:                    if (status != SOCKET_STATUS_PENDING) {
0336:                        throw new NoConnectionPendingException();
0337:                    }
0338:                }
0339:
0340:                // finish result
0341:                int result = EOF;
0342:                boolean finished = false;
0343:
0344:                try {
0345:                    begin();
0346:                    result = networkSystem.connectWithTimeout(fd,
0347:                            isBlocking() ? -1 : 0, trafficClass, connectAddress
0348:                                    .getAddress(), connectAddress.getPort(),
0349:                            HY_PORT_SOCKET_STEP_CHECK, connectContext);
0350:                    finished = (result == CONNECT_SUCCESS);
0351:                    isBound = finished;
0352:                    localAddress = networkSystem.getSocketLocalAddress(fd,
0353:                            false);
0354:                } catch (ConnectException e) {
0355:                    if (isOpen()) {
0356:                        close();
0357:                        finished = true;
0358:                    }
0359:                    throw e;
0360:                } finally {
0361:                    end(finished);
0362:                }
0363:
0364:                synchronized (this ) {
0365:                    status = (finished ? SOCKET_STATUS_CONNECTED : status);
0366:                    isBound = finished;
0367:                }
0368:                return finished;
0369:            }
0370:
0371:            /**
0372:             * @see java.nio.channels.SocketChannel#read(java.nio.ByteBuffer)
0373:             */
0374:            @Override
0375:            public int read(ByteBuffer target) throws IOException {
0376:                if (null == target) {
0377:                    throw new NullPointerException();
0378:                }
0379:                checkOpenConnected();
0380:                if (!target.hasRemaining()) {
0381:                    return 0;
0382:                }
0383:
0384:                int readCount;
0385:                if (target.isDirect() || target.hasArray()) {
0386:                    readCount = readImpl(target);
0387:                    if (readCount > 0) {
0388:                        target.position(target.position() + readCount);
0389:                    }
0390:                } else {
0391:                    ByteBuffer readBuffer = null;
0392:                    byte[] readArray = null;
0393:                    readArray = new byte[target.remaining()];
0394:                    readBuffer = ByteBuffer.wrap(readArray);
0395:                    readCount = readImpl(readBuffer);
0396:                    if (readCount > 0) {
0397:                        target.put(readArray, 0, readCount);
0398:                    }
0399:                }
0400:                return readCount;
0401:            }
0402:
0403:            /**
0404:             * @see java.nio.channels.SocketChannel#read(java.nio.ByteBuffer[], int,
0405:             *      int)
0406:             */
0407:            @Override
0408:            public long read(ByteBuffer[] targets, int offset, int length)
0409:                    throws IOException {
0410:                if (!isIndexValid(targets, offset, length)) {
0411:                    throw new IndexOutOfBoundsException();
0412:                }
0413:
0414:                checkOpenConnected();
0415:                int totalCount = calculateByteBufferArray(targets, offset,
0416:                        length);
0417:                if (0 == totalCount) {
0418:                    return 0;
0419:                }
0420:                byte[] readArray = new byte[totalCount];
0421:                ByteBuffer readBuffer = ByteBuffer.wrap(readArray);
0422:                int readCount;
0423:                // read data to readBuffer, and then transfer data from readBuffer to
0424:                // targets.
0425:                readCount = readImpl(readBuffer);
0426:                if (readCount > 0) {
0427:                    int left = readCount;
0428:                    int index = offset;
0429:                    // transfer data from readArray to targets
0430:                    while (left > 0) {
0431:                        int putLength = Math.min(targets[index].remaining(),
0432:                                left);
0433:                        targets[index].put(readArray, readCount - left,
0434:                                putLength);
0435:                        index++;
0436:                        left -= putLength;
0437:                    }
0438:                }
0439:                return readCount;
0440:            }
0441:
0442:            private boolean isIndexValid(ByteBuffer[] targets, int offset,
0443:                    int length) {
0444:                return (length >= 0) && (offset >= 0)
0445:                        && ((long) length + (long) offset <= targets.length);
0446:            }
0447:
0448:            /**
0449:             * Read from channel, and store the result in the target.
0450:             * 
0451:             * @param target
0452:             *            output parameter
0453:             */
0454:            private int readImpl(ByteBuffer target) throws IOException {
0455:                synchronized (readLock) {
0456:                    int readCount = 0;
0457:                    try {
0458:                        if (isBlocking()) {
0459:                            begin();
0460:                        }
0461:                        int offset = target.position();
0462:                        int length = target.remaining();
0463:                        if (target.isDirect()) {
0464:                            long address = AddressUtil
0465:                                    .getDirectBufferAddress(target);
0466:                            readCount = networkSystem.readDirect(fd, address
0467:                                    + offset, length,
0468:                                    (isBlocking() ? TIMEOUT_BLOCK
0469:                                            : TIMEOUT_NONBLOCK));
0470:                        } else {
0471:                            // target is assured to have array.
0472:                            byte[] array = target.array();
0473:                            offset += target.arrayOffset();
0474:                            readCount = networkSystem.read(fd, array, offset,
0475:                                    length, (isBlocking() ? TIMEOUT_BLOCK
0476:                                            : TIMEOUT_NONBLOCK));
0477:                        }
0478:                        return readCount;
0479:                    } finally {
0480:                        if (isBlocking()) {
0481:                            end(readCount > 0);
0482:                        }
0483:                    }
0484:                }
0485:            }
0486:
0487:            /**
0488:             * @see java.nio.channels.SocketChannel#write(java.nio.ByteBuffer)
0489:             */
0490:            @Override
0491:            public int write(ByteBuffer source) throws IOException {
0492:                if (null == source) {
0493:                    throw new NullPointerException();
0494:                }
0495:                checkOpenConnected();
0496:                if (!source.hasRemaining()) {
0497:                    return 0;
0498:                }
0499:                return writeImpl(source);
0500:            }
0501:
0502:            /**
0503:             * @see java.nio.channels.SocketChannel#write(java.nio.ByteBuffer[], int,
0504:             *      int)
0505:             */
0506:            @Override
0507:            public long write(ByteBuffer[] sources, int offset, int length)
0508:                    throws IOException {
0509:                if (!isIndexValid(sources, offset, length)) {
0510:                    throw new IndexOutOfBoundsException();
0511:                }
0512:
0513:                checkOpenConnected();
0514:                int count = calculateByteBufferArray(sources, offset, length);
0515:                if (0 == count) {
0516:                    return 0;
0517:                }
0518:                ByteBuffer writeBuf = ByteBuffer.allocate(count);
0519:                for (int val = offset; val < length + offset; val++) {
0520:                    ByteBuffer source = sources[val];
0521:                    int oldPosition = source.position();
0522:                    writeBuf.put(source);
0523:                    source.position(oldPosition);
0524:                }
0525:                writeBuf.flip();
0526:                int result = writeImpl(writeBuf);
0527:                int val = offset;
0528:                int written = result;
0529:                while (result > 0) {
0530:                    ByteBuffer source = sources[val];
0531:                    int gap = Math.min(result, source.remaining());
0532:                    source.position(source.position() + gap);
0533:                    val++;
0534:                    result -= gap;
0535:                }
0536:                return written;
0537:            }
0538:
0539:            private int calculateByteBufferArray(ByteBuffer[] sources,
0540:                    int offset, int length) {
0541:                int sum = 0;
0542:                for (int val = offset; val < offset + length; val++) {
0543:                    sum = sum + sources[val].remaining();
0544:                }
0545:                return sum;
0546:            }
0547:
0548:            /*
0549:             * Write the source. return the count of bytes written.
0550:             */
0551:            private int writeImpl(ByteBuffer source) throws IOException {
0552:                synchronized (writeLock) {
0553:                    if (!source.hasRemaining()) {
0554:                        return 0;
0555:                    }
0556:                    int writeCount = 0;
0557:                    try {
0558:                        int pos = source.position();
0559:                        int length = source.remaining();
0560:                        if (isBlocking()) {
0561:                            begin();
0562:                        }
0563:                        if (source.isDirect()) {
0564:                            long address = AddressUtil
0565:                                    .getDirectBufferAddress(source);
0566:                            writeCount = networkSystem.writeDirect(fd, address
0567:                                    + pos, length);
0568:                        } else if (source.hasArray()) {
0569:                            pos += source.arrayOffset();
0570:                            writeCount = networkSystem.write(fd,
0571:                                    source.array(), pos, length);
0572:                        } else {
0573:                            byte[] array = new byte[length];
0574:                            source.get(array);
0575:                            writeCount = networkSystem.write(fd, array, 0,
0576:                                    length);
0577:                        }
0578:                        source.position(pos + writeCount);
0579:                    } catch (SocketException e) {
0580:                        if (e.getCause() instanceof  ErrorCodeException) {
0581:                            if (ERRCODE_SOCKET_NONBLOCKING_WOULD_BLOCK == ((ErrorCodeException) e
0582:                                    .getCause()).getErrorCode()) {
0583:                                return writeCount;
0584:                            }
0585:                        }
0586:                        throw e;
0587:                    } finally {
0588:                        if (isBlocking()) {
0589:                            end(writeCount >= 0);
0590:                        }
0591:                    }
0592:                    return writeCount;
0593:                }
0594:            }
0595:
0596:            /*
0597:             * Status check, open and "connected", when read and write.
0598:             */
0599:            synchronized private void checkOpenConnected()
0600:                    throws ClosedChannelException {
0601:                if (!isOpen()) {
0602:                    throw new ClosedChannelException();
0603:                }
0604:                if (!isConnected()) {
0605:                    throw new NotYetConnectedException();
0606:                }
0607:            }
0608:
0609:            /*
0610:             * Status check, open and "unconnected", before connection.
0611:             */
0612:            synchronized private void checkUnconnected() throws IOException {
0613:                if (!isOpen()) {
0614:                    throw new ClosedChannelException();
0615:                }
0616:                if (status == SOCKET_STATUS_CONNECTED) {
0617:                    throw new AlreadyConnectedException();
0618:                }
0619:                if (status == SOCKET_STATUS_PENDING) {
0620:                    throw new ConnectionPendingException();
0621:                }
0622:            }
0623:
0624:            /*
0625:             * Shared by this class and DatagramChannelImpl, to do the address transfer
0626:             * and check.
0627:             */
0628:            static InetSocketAddress validateAddress(SocketAddress socketAddress) {
0629:                if (null == socketAddress) {
0630:                    throw new IllegalArgumentException();
0631:                }
0632:                if (!(socketAddress instanceof  InetSocketAddress)) {
0633:                    throw new UnsupportedAddressTypeException();
0634:                }
0635:                InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress;
0636:                if (inetSocketAddress.isUnresolved()) {
0637:                    throw new UnresolvedAddressException();
0638:                }
0639:                return inetSocketAddress;
0640:            }
0641:
0642:            /*
0643:             * Get local address.
0644:             */
0645:            public InetAddress getLocalAddress() throws UnknownHostException {
0646:                byte[] any_bytes = { 0, 0, 0, 0 };
0647:                if (!isBound) {
0648:                    return InetAddress.getByAddress(any_bytes);
0649:                }
0650:                return localAddress;
0651:            }
0652:
0653:            /*
0654:             * Do really closing action here.
0655:             */
0656:            @Override
0657:            synchronized protected void implCloseSelectableChannel()
0658:                    throws IOException {
0659:                if (SOCKET_STATUS_CLOSED != status) {
0660:                    status = SOCKET_STATUS_CLOSED;
0661:                    if (null != socket && !socket.isClosed()) {
0662:                        socket.close();
0663:                    } else {
0664:                        networkSystem.socketClose(fd);
0665:                    }
0666:                }
0667:            }
0668:
0669:            /**
0670:             * @see java.nio.channels.spi.AbstractSelectableChannel#implConfigureBlocking(boolean)
0671:             */
0672:            @Override
0673:            protected void implConfigureBlocking(boolean blockMode)
0674:                    throws IOException {
0675:                synchronized (blockingLock()) {
0676:                    networkSystem.setNonBlocking(fd, !blockMode);
0677:                }
0678:            }
0679:
0680:            /*
0681:             * Get the fd.
0682:             */
0683:            public FileDescriptor getFD() {
0684:                return fd;
0685:            }
0686:
0687:            /*
0688:             * Adapter classes for internal socket.
0689:             */
0690:            private static class SocketAdapter extends Socket {
0691:
0692:                SocketChannelImpl channel;
0693:
0694:                SocketImpl socketImpl;
0695:
0696:                SocketAdapter(SocketImpl socketimpl, SocketChannelImpl channel)
0697:                        throws SocketException {
0698:                    super (socketimpl);
0699:                    socketImpl = socketimpl;
0700:                    this .channel = channel;
0701:                }
0702:
0703:                /**
0704:                 * @see java.net.Socket#getChannel()
0705:                 */
0706:                @Override
0707:                public SocketChannel getChannel() {
0708:                    return channel;
0709:                }
0710:
0711:                /**
0712:                 * @see java.net.Socket#isBound()
0713:                 */
0714:                @Override
0715:                public boolean isBound() {
0716:                    return channel.isBound;
0717:                }
0718:
0719:                /**
0720:                 * @see java.net.Socket#isConnected()
0721:                 */
0722:                @Override
0723:                public boolean isConnected() {
0724:                    return channel.isConnected();
0725:                }
0726:
0727:                /**
0728:                 * @see java.net.Socket#getLocalAddress()
0729:                 */
0730:                @Override
0731:                public InetAddress getLocalAddress() {
0732:                    try {
0733:                        return channel.getLocalAddress();
0734:                    } catch (UnknownHostException e) {
0735:                        return null;
0736:                    }
0737:                }
0738:
0739:                /**
0740:                 * @see java.net.Socket#connect(java.net.SocketAddress, int)
0741:                 */
0742:                @Override
0743:                public void connect(SocketAddress remoteAddr, int timeout)
0744:                        throws IOException {
0745:                    if (!channel.isBlocking()) {
0746:                        throw new IllegalBlockingModeException();
0747:                    }
0748:                    if (isConnected()) {
0749:                        throw new AlreadyConnectedException();
0750:                    }
0751:                    super .connect(remoteAddr, timeout);
0752:                    channel.localAddress = networkSystem.getSocketLocalAddress(
0753:                            channel.fd, false);
0754:                    if (super .isConnected()) {
0755:                        channel.setConnected();
0756:                        channel.isBound = super .isBound();
0757:                    }
0758:                }
0759:
0760:                /**
0761:                 * @see java.net.Socket#bind(java.net.SocketAddress)
0762:                 */
0763:                @Override
0764:                public void bind(SocketAddress localAddr) throws IOException {
0765:                    if (channel.isConnected()) {
0766:                        throw new AlreadyConnectedException();
0767:                    }
0768:                    if (SocketChannelImpl.SOCKET_STATUS_PENDING == channel.status) {
0769:                        throw new ConnectionPendingException();
0770:                    }
0771:                    super .bind(localAddr);
0772:                    // keep here to see if need next version
0773:                    // channel.Address = getLocalSocketAddress();
0774:                    // channel.localport = getLocalPort();
0775:                    channel.isBound = true;
0776:
0777:                }
0778:
0779:                /**
0780:                 * @see java.net.Socket#close()
0781:                 */
0782:                @Override
0783:                public void close() throws IOException {
0784:                    synchronized (channel) {
0785:                        if (channel.isOpen()) {
0786:                            channel.close();
0787:                        } else {
0788:                            super .close();
0789:                        }
0790:                        channel.status = SocketChannelImpl.SOCKET_STATUS_CLOSED;
0791:                    }
0792:                }
0793:
0794:                @Override
0795:                public boolean getReuseAddress() throws SocketException {
0796:                    checkOpen();
0797:                    return ((Boolean) socketImpl
0798:                            .getOption(SocketOptions.SO_REUSEADDR))
0799:                            .booleanValue();
0800:                }
0801:
0802:                @Override
0803:                public synchronized int getReceiveBufferSize()
0804:                        throws SocketException {
0805:                    checkOpen();
0806:                    return ((Integer) socketImpl
0807:                            .getOption(SocketOptions.SO_RCVBUF)).intValue();
0808:                }
0809:
0810:                @Override
0811:                public synchronized int getSendBufferSize()
0812:                        throws SocketException {
0813:                    checkOpen();
0814:                    return ((Integer) socketImpl
0815:                            .getOption(SocketOptions.SO_SNDBUF)).intValue();
0816:                }
0817:
0818:                @Override
0819:                public synchronized int getSoTimeout() throws SocketException {
0820:                    checkOpen();
0821:                    return ((Integer) socketImpl
0822:                            .getOption(SocketOptions.SO_TIMEOUT)).intValue();
0823:                }
0824:
0825:                @Override
0826:                public int getTrafficClass() throws SocketException {
0827:                    checkOpen();
0828:                    return ((Number) socketImpl.getOption(SocketOptions.IP_TOS))
0829:                            .intValue();
0830:                }
0831:
0832:                /**
0833:                 * @see java.net.Socket#getKeepAlive()
0834:                 */
0835:                @Override
0836:                public boolean getKeepAlive() throws SocketException {
0837:                    checkOpen();
0838:                    return ((Boolean) socketImpl
0839:                            .getOption(SocketOptions.SO_KEEPALIVE))
0840:                            .booleanValue();
0841:                }
0842:
0843:                /**
0844:                 * @see java.net.Socket#getOOBInline()
0845:                 */
0846:                @Override
0847:                public boolean getOOBInline() throws SocketException {
0848:                    checkOpen();
0849:                    return ((Boolean) socketImpl
0850:                            .getOption(SocketOptions.SO_OOBINLINE))
0851:                            .booleanValue();
0852:                }
0853:
0854:                /**
0855:                 * @see java.net.Socket#getSoLinger()
0856:                 */
0857:                @Override
0858:                public int getSoLinger() throws SocketException {
0859:                    checkOpen();
0860:                    return ((Integer) socketImpl
0861:                            .getOption(SocketOptions.SO_LINGER)).intValue();
0862:                }
0863:
0864:                /**
0865:                 * @see java.net.Socket#getTcpNoDelay()
0866:                 */
0867:                @Override
0868:                public boolean getTcpNoDelay() throws SocketException {
0869:                    checkOpen();
0870:                    return ((Boolean) socketImpl
0871:                            .getOption(SocketOptions.TCP_NODELAY))
0872:                            .booleanValue();
0873:                }
0874:
0875:                /**
0876:                 * @see java.net.Socket#getOutputStream()
0877:                 */
0878:                @Override
0879:                public OutputStream getOutputStream() throws IOException {
0880:                    if (!channel.isOpen()) {
0881:                        // nio.00=Socket is closed
0882:                        throw new SocketException(Messages.getString("nio.00")); //$NON-NLS-1$
0883:                    }
0884:                    if (!channel.isConnected()) {
0885:                        // nio.01=Socket is not connected
0886:                        throw new SocketException(Messages.getString("nio.01")); //$NON-NLS-1$
0887:                    }
0888:                    if (isOutputShutdown()) {
0889:                        // nio.02=Socket output is shutdown
0890:                        throw new SocketException(Messages.getString("nio.02")); //$NON-NLS-1$
0891:                    }
0892:                    return new SocketChannelOutputStream(channel);
0893:                }
0894:
0895:                /**
0896:                 * @see java.net.Socket#getInputStream()
0897:                 */
0898:                @Override
0899:                public InputStream getInputStream() throws IOException {
0900:                    if (!channel.isOpen()) {
0901:                        // nio.00=Socket is closed
0902:                        throw new SocketException(Messages.getString("nio.00")); //$NON-NLS-1$
0903:                    }
0904:                    if (!channel.isConnected()) {
0905:                        // nio.01=Socket is not connected
0906:                        throw new SocketException(Messages.getString("nio.01")); //$NON-NLS-1$
0907:                    }
0908:                    if (isInputShutdown()) {
0909:                        // nio.03=Socket input is shutdown
0910:                        throw new SocketException(Messages.getString("nio.03")); //$NON-NLS-1$
0911:                    }
0912:                    return new SocketChannelInputStream(channel);
0913:                }
0914:
0915:                /*
0916:                 * Checks whether the channel is open.
0917:                 */
0918:                private void checkOpen() throws SocketException {
0919:                    if (isClosed()) {
0920:                        // nio.00=Socket is closed
0921:                        throw new SocketException(Messages.getString("nio.00")); //$NON-NLS-1$
0922:                    }
0923:                }
0924:
0925:                /*
0926:                 * Used for net and nio exchange.
0927:                 */
0928:                public SocketImpl getImpl() {
0929:                    return socketImpl;
0930:                }
0931:            }
0932:
0933:            /*
0934:             * This output stream delegates all operations to the associated channel.
0935:             * Throws an IllegalBlockingModeException if the channel is in non-blocking
0936:             * mode when performing write operations.
0937:             */
0938:            private static class SocketChannelOutputStream extends OutputStream {
0939:                SocketChannel channel;
0940:
0941:                public SocketChannelOutputStream(SocketChannel channel) {
0942:                    this .channel = channel;
0943:                }
0944:
0945:                /*
0946:                 * Closes this stream and channel.
0947:                 * 
0948:                 * @exception IOException thrown if an error occurs during the close
0949:                 */
0950:                @Override
0951:                public void close() throws IOException {
0952:                    channel.close();
0953:                }
0954:
0955:                /**
0956:                 * @see java.io.OutputStream#write(byte[], int, int)
0957:                 */
0958:                @Override
0959:                public void write(byte[] buffer, int offset, int count)
0960:                        throws IOException {
0961:                    if (0 > offset || 0 > count
0962:                            || count + offset > buffer.length) {
0963:                        throw new IndexOutOfBoundsException();
0964:                    }
0965:                    ByteBuffer buf = ByteBuffer.wrap(buffer, offset, count);
0966:                    if (!channel.isBlocking()) {
0967:                        throw new IllegalBlockingModeException();
0968:                    }
0969:                    channel.write(buf);
0970:                }
0971:
0972:                /**
0973:                 * @see java.io.OutputStream#write(int)
0974:                 */
0975:                @Override
0976:                public void write(int oneByte) throws IOException {
0977:                    if (!channel.isBlocking()) {
0978:                        throw new IllegalBlockingModeException();
0979:                    }
0980:                    ByteBuffer buffer = ByteBuffer.allocate(1);
0981:                    buffer.put(0, (byte) (oneByte & 0xFF));
0982:                    channel.write(buffer);
0983:                }
0984:            }
0985:
0986:            /*
0987:             * This input stream delegates all operations to the associated channel.
0988:             * Throws an IllegalBlockingModeException if the channel is in non-blocking
0989:             * mode when performing read operations.
0990:             */
0991:            private static class SocketChannelInputStream extends InputStream {
0992:                SocketChannel channel;
0993:
0994:                public SocketChannelInputStream(SocketChannel channel) {
0995:                    this .channel = channel;
0996:                }
0997:
0998:                /*
0999:                 * Closes this stream and channel.
1000:                 */
1001:                @Override
1002:                public void close() throws IOException {
1003:                    channel.close();
1004:                }
1005:
1006:                /**
1007:                 * @see java.io.InputStream#read()
1008:                 */
1009:                @Override
1010:                public int read() throws IOException {
1011:                    if (!channel.isBlocking()) {
1012:                        throw new IllegalBlockingModeException();
1013:                    }
1014:                    ByteBuffer buf = ByteBuffer.allocate(1);
1015:                    int result = channel.read(buf);
1016:                    return (-1 == result) ? result : buf.get() & 0xFF;
1017:                }
1018:
1019:                /**
1020:                 * @see java.io.InputStream#read(byte[], int, int)
1021:                 */
1022:                @Override
1023:                public int read(byte[] buffer, int offset, int count)
1024:                        throws IOException {
1025:                    if (0 > offset || 0 > count
1026:                            || count + offset > buffer.length) {
1027:                        throw new IndexOutOfBoundsException();
1028:                    }
1029:                    if (!channel.isBlocking()) {
1030:                        throw new IllegalBlockingModeException();
1031:                    }
1032:                    ByteBuffer buf = ByteBuffer.wrap(buffer, offset, count);
1033:                    return channel.read(buf);
1034:                }
1035:            }
1036:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.