Source Code Cross Referenced for PlainDatagramSocketImpl.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.InterruptedIOException;
023:        import java.net.DatagramPacket;
024:        import java.net.DatagramSocketImpl;
025:        import java.net.InetAddress;
026:        import java.net.InetSocketAddress;
027:        import java.net.NetworkInterface;
028:        import java.net.SocketAddress;
029:        import java.net.SocketException;
030:        import java.net.SocketOptions;
031:        import java.net.SocketTimeoutException;
032:        import java.net.UnknownHostException;
033:        import java.security.AccessController;
034:
035:        import org.apache.harmony.luni.platform.INetworkSystem;
036:        import org.apache.harmony.luni.platform.Platform;
037:        import org.apache.harmony.luni.util.Msg;
038:        import org.apache.harmony.luni.util.PriviAction;
039:
040:        /**
041:         * The default, concrete instance of datagram sockets. This class does not
042:         * support security checks. Alternative types of DatagramSocketImpl's may be
043:         * used by setting the <code>impl.prefix</code> system property.
044:         */
045:        class PlainDatagramSocketImpl extends DatagramSocketImpl {
046:
047:            static final int MULTICAST_IF = 1;
048:
049:            static final int MULTICAST_TTL = 2;
050:
051:            static final int TCP_NODELAY = 4;
052:
053:            static final int FLAG_SHUTDOWN = 8;
054:
055:            private final static int SO_BROADCAST = 32;
056:
057:            final static int IP_MULTICAST_ADD = 19;
058:
059:            final static int IP_MULTICAST_DROP = 20;
060:
061:            final static int IP_MULTICAST_TTL = 17;
062:
063:            /**
064:             * for datagram and multicast sockets we have to set REUSEADDR and REUSEPORT
065:             * when REUSEADDR is set for other types of sockets we need to just set
066:             * REUSEADDR therefore we have this other option which sets both if
067:             * supported by the platform. this cannot be in SOCKET_OPTIONS because since
068:             * it is a public interface it ends up being public even if it is not
069:             * declared public
070:             */
071:            static final int REUSEADDR_AND_REUSEPORT = 10001;
072:
073:            private boolean bindToDevice;
074:
075:            private byte[] ipaddress = { 0, 0, 0, 0 };
076:
077:            private int ttl = 1;
078:
079:            private INetworkSystem netImpl = Platform.getNetworkSystem();
080:
081:            private volatile boolean isNativeConnected;
082:
083:            public int receiveTimeout;
084:
085:            public boolean streaming = true;
086:
087:            public boolean shutdownInput;
088:
089:            /**
090:             * used to keep address to which the socket was connected to at the native
091:             * level
092:             */
093:            private InetAddress connectedAddress;
094:
095:            private int connectedPort = -1;
096:
097:            /**
098:             * used to store the trafficClass value which is simply returned as the
099:             * value that was set. We also need it to pass it to methods that specify an
100:             * address packets are going to be sent to
101:             */
102:            private int trafficClass;
103:
104:            public PlainDatagramSocketImpl(FileDescriptor fd, int localPort) {
105:                super ();
106:                this .fd = fd;
107:                this .localPort = localPort;
108:            }
109:
110:            public PlainDatagramSocketImpl() {
111:                super ();
112:                fd = new FileDescriptor();
113:            }
114:
115:            @Override
116:            public void bind(int port, InetAddress addr) throws SocketException {
117:                String prop = AccessController
118:                        .doPrivileged(new PriviAction<String>("bindToDevice")); //$NON-NLS-1$
119:                boolean useBindToDevice = prop != null
120:                        && prop.toLowerCase().equals("true"); //$NON-NLS-1$
121:                bindToDevice = netImpl.bind2(fd, port, useBindToDevice, addr);
122:                if (0 != port) {
123:                    localPort = port;
124:                } else {
125:                    localPort = netImpl.getSocketLocalPort(fd, NetUtil
126:                            .preferIPv6Addresses());
127:                }
128:
129:                try {
130:                    // Ignore failures
131:                    setOption(SO_BROADCAST, Boolean.TRUE);
132:                } catch (IOException e) {
133:                }
134:            }
135:
136:            @Override
137:            public void close() {
138:                synchronized (fd) {
139:                    if (fd.valid()) {
140:                        try {
141:                            netImpl.socketClose(fd);
142:                        } catch (IOException e) {
143:                        }
144:                        fd = new FileDescriptor();
145:                    }
146:                }
147:            }
148:
149:            @Override
150:            public void create() throws SocketException {
151:                netImpl.createDatagramSocket(fd, NetUtil.preferIPv4Stack());
152:            }
153:
154:            @Override
155:            protected void finalize() {
156:                close();
157:            }
158:
159:            @Override
160:            public Object getOption(int optID) throws SocketException {
161:                if (optID == SocketOptions.SO_TIMEOUT) {
162:                    return Integer.valueOf(receiveTimeout);
163:                } else if (optID == SocketOptions.IP_TOS) {
164:                    return Integer.valueOf(trafficClass);
165:                } else {
166:                    // Call the native first so there will be
167:                    // an exception if the socket if closed.
168:                    Object result = netImpl.getSocketOption(fd, optID);
169:                    if (optID == SocketOptions.IP_MULTICAST_IF
170:                            && (netImpl.getSocketFlags() & MULTICAST_IF) != 0) {
171:                        try {
172:                            return InetAddress.getByAddress(ipaddress);
173:                        } catch (UnknownHostException e) {
174:                            return null;
175:                        }
176:                    }
177:                    return result;
178:                }
179:            }
180:
181:            @Override
182:            public int getTimeToLive() throws IOException {
183:                // Call the native first so there will be an exception if the socket if
184:                // closed.
185:                int result = (((Byte) getOption(IP_MULTICAST_TTL)).byteValue()) & 0xFF;
186:                if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
187:                    return ttl;
188:                }
189:                return result;
190:            }
191:
192:            @Override
193:            public byte getTTL() throws IOException {
194:                // Call the native first so there will be an exception if the socket if
195:                // closed.
196:                byte result = ((Byte) getOption(IP_MULTICAST_TTL)).byteValue();
197:                if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
198:                    return (byte) ttl;
199:                }
200:                return result;
201:            }
202:
203:            @Override
204:            public void join(InetAddress addr) throws IOException {
205:                setOption(IP_MULTICAST_ADD, new GenericIPMreq(addr));
206:            }
207:
208:            @Override
209:            public void joinGroup(SocketAddress addr,
210:                    NetworkInterface netInterface) throws IOException {
211:                if (addr instanceof  InetSocketAddress) {
212:                    InetAddress groupAddr = ((InetSocketAddress) addr)
213:                            .getAddress();
214:                    setOption(IP_MULTICAST_ADD, new GenericIPMreq(groupAddr,
215:                            netInterface));
216:                }
217:            }
218:
219:            @Override
220:            public void leave(InetAddress addr) throws IOException {
221:                setOption(IP_MULTICAST_DROP, new GenericIPMreq(addr));
222:            }
223:
224:            @Override
225:            public void leaveGroup(SocketAddress addr,
226:                    NetworkInterface netInterface) throws IOException {
227:                if (addr instanceof  InetSocketAddress) {
228:                    InetAddress groupAddr = ((InetSocketAddress) addr)
229:                            .getAddress();
230:                    setOption(IP_MULTICAST_DROP, new GenericIPMreq(groupAddr,
231:                            netInterface));
232:                }
233:            }
234:
235:            @Override
236:            protected int peek(InetAddress sender) throws IOException {
237:                if (isNativeConnected) {
238:                    /*
239:                     * in this case we know the port and address from which the data
240:                     * must have be been received as the socket is connected. However,
241:                     * we still need to do the receive in order to know that there was
242:                     * data received. We use a short buffer as we don't actually need
243:                     * the packet, only the knowledge that it is there
244:                     */
245:                    byte[] storageArray = new byte[10];
246:                    DatagramPacket pack = new DatagramPacket(storageArray,
247:                            storageArray.length);
248:                    netImpl.recvConnectedDatagram(fd, pack, pack.getData(),
249:                            pack.getOffset(), pack.getLength(), receiveTimeout,
250:                            true); // peek
251:                    // to set the sender ,we now use a native function
252:                    // sender.ipaddress = connectedAddress.getAddress();
253:                    netImpl.setInetAddress(sender, connectedAddress
254:                            .getAddress());
255:                    return connectedPort;
256:                }
257:                return netImpl.peekDatagram(fd, sender, receiveTimeout);
258:            }
259:
260:            @Override
261:            public void receive(DatagramPacket pack) throws java.io.IOException {
262:                try {
263:                    if (isNativeConnected) {
264:                        // do not peek
265:                        netImpl.recvConnectedDatagram(fd, pack, pack.getData(),
266:                                pack.getOffset(), pack.getLength(),
267:                                receiveTimeout, false);
268:                        updatePacketRecvAddress(pack);
269:                    } else {
270:                        // receiveDatagramImpl2
271:                        netImpl.receiveDatagram(fd, pack, pack.getData(), pack
272:                                .getOffset(), pack.getLength(), receiveTimeout,
273:                                false);
274:                    }
275:                } catch (InterruptedIOException e) {
276:                    throw new SocketTimeoutException(e.getMessage());
277:                }
278:            }
279:
280:            @Override
281:            public void send(DatagramPacket packet) throws IOException {
282:
283:                if (isNativeConnected) {
284:                    netImpl.sendConnectedDatagram(fd, packet.getData(), packet
285:                            .getOffset(), packet.getLength(), bindToDevice);
286:                } else {
287:                    // sendDatagramImpl2
288:                    netImpl.sendDatagram(fd, packet.getData(), packet
289:                            .getOffset(), packet.getLength(), packet.getPort(),
290:                            bindToDevice, trafficClass, packet.getAddress());
291:                }
292:            }
293:
294:            /**
295:             * Set the nominated socket option. As the timeouts are not set as options
296:             * in the IP stack, the value is stored in an instance field.
297:             * 
298:             * @throws SocketException thrown if the option value is unsupported or
299:             *         invalid
300:             */
301:            @Override
302:            public void setOption(int optID, Object val) throws SocketException {
303:                /*
304:                 * for datagram sockets on some platforms we have to set both the
305:                 * REUSEADDR AND REUSEPORT so for REUSEADDR set this option option which
306:                 * tells the VM to set the two values as appropriate for the platform
307:                 */
308:                if (optID == SocketOptions.SO_REUSEADDR) {
309:                    optID = REUSEADDR_AND_REUSEPORT;
310:                }
311:
312:                if (optID == SocketOptions.SO_TIMEOUT) {
313:                    receiveTimeout = ((Integer) val).intValue();
314:                } else {
315:                    int flags = netImpl.getSocketFlags();
316:                    try {
317:                        netImpl.setSocketOption(fd, optID | (flags << 16), val);
318:                    } catch (SocketException e) {
319:                        // we don't throw an exception for IP_TOS even if the platform
320:                        // won't let us set the requested value
321:                        if (optID != SocketOptions.IP_TOS) {
322:                            throw e;
323:                        }
324:                    }
325:                    if (optID == SocketOptions.IP_MULTICAST_IF
326:                            && (flags & MULTICAST_IF) != 0) {
327:                        InetAddress inet = (InetAddress) val;
328:                        if (NetUtil.bytesToInt(inet.getAddress(), 0) == 0
329:                                || inet.isLoopbackAddress()) {
330:                            ipaddress = ((InetAddress) val).getAddress();
331:                        } else {
332:                            InetAddress local = null;
333:                            try {
334:                                local = InetAddress.getLocalHost();
335:                            } catch (UnknownHostException e) {
336:                                throw new SocketException("getLocalHost(): "
337:                                        + e.toString());
338:                            }
339:                            if (inet.equals(local)) {
340:                                ipaddress = ((InetAddress) val).getAddress();
341:                            } else {
342:                                throw new SocketException(val
343:                                        + " != getLocalHost(): " + local);
344:                            }
345:                        }
346:                    }
347:                    /*
348:                     * save this value as it is actually used differently for IPv4 and
349:                     * IPv6 so we cannot get the value using the getOption. The option
350:                     * is actually only set for IPv4 and a masked version of the value
351:                     * will be set as only a subset of the values are allowed on the
352:                     * socket. Therefore we need to retain it to return the value that
353:                     * was set. We also need the value to be passed into a number of
354:                     * natives so that it can be used properly with IPv6
355:                     */
356:                    if (optID == SocketOptions.IP_TOS) {
357:                        trafficClass = ((Integer) val).intValue();
358:                    }
359:                }
360:            }
361:
362:            @Override
363:            public void setTimeToLive(int ttl) throws java.io.IOException {
364:                setOption(IP_MULTICAST_TTL, Byte.valueOf((byte) (ttl & 0xFF)));
365:                if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
366:                    this .ttl = ttl;
367:                }
368:            }
369:
370:            @Override
371:            public void setTTL(byte ttl) throws java.io.IOException {
372:                setOption(IP_MULTICAST_TTL, Byte.valueOf(ttl));
373:                if ((netImpl.getSocketFlags() & MULTICAST_TTL) != 0) {
374:                    this .ttl = ttl;
375:                }
376:            }
377:
378:            @Override
379:            public void connect(InetAddress inetAddr, int port)
380:                    throws SocketException {
381:
382:                // connectDatagram impl2
383:                netImpl.connectDatagram(fd, port, trafficClass, inetAddr);
384:
385:                // if we get here then we are connected at the native level
386:                try {
387:                    connectedAddress = InetAddress.getByAddress(inetAddr
388:                            .getAddress());
389:                } catch (UnknownHostException e) {
390:                    // this is never expected to happen as we should not have gotten
391:                    // here if the address is not resolvable
392:                    throw new SocketException(Msg.getString(
393:                            "K0317", inetAddr.getHostName())); //$NON-NLS-1$
394:                }
395:                connectedPort = port;
396:                isNativeConnected = true;
397:            }
398:
399:            @Override
400:            public void disconnect() {
401:                try {
402:                    netImpl.disconnectDatagram(fd);
403:                } catch (Exception e) {
404:                    // there is currently no way to return an error so just eat any
405:                    // exception
406:                }
407:                connectedPort = -1;
408:                connectedAddress = null;
409:                isNativeConnected = false;
410:            }
411:
412:            @Override
413:            public int peekData(DatagramPacket pack) throws IOException {
414:                try {
415:                    if (isNativeConnected) {
416:                        netImpl.recvConnectedDatagram(fd, pack, pack.getData(),
417:                                pack.getOffset(), pack.getLength(),
418:                                receiveTimeout, true); // peek
419:                        updatePacketRecvAddress(pack);
420:                    } else {
421:                        // receiveDatagram 2
422:                        netImpl.receiveDatagram(fd, pack, pack.getData(), pack
423:                                .getOffset(), pack.getLength(), receiveTimeout,
424:                                true); // peek
425:                    }
426:                } catch (InterruptedIOException e) {
427:                    throw new SocketTimeoutException(e.toString());
428:                }
429:                return pack.getPort();
430:            }
431:
432:            /**
433:             * Set the received address and port in the packet. We do this when the
434:             * Datagram socket is connected at the native level and the
435:             * recvConnnectedDatagramImpl does not update the packet with address from
436:             * which the packet was received
437:             * 
438:             * @param packet
439:             *            the packet to be updated
440:             */
441:            private void updatePacketRecvAddress(DatagramPacket packet) {
442:                packet.setAddress(connectedAddress);
443:                packet.setPort(connectedPort);
444:            }
445:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.