Source Code Cross Referenced for DatagramSocket.java in  » 6.0-JDK-Core » net » java » net » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
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
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » net » java.net 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1995-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package java.net;
0027
0028        import java.io.FileDescriptor;
0029        import java.io.IOException;
0030        import java.io.InterruptedIOException;
0031        import java.nio.channels.DatagramChannel;
0032        import java.security.AccessController;
0033        import java.security.PrivilegedExceptionAction;
0034
0035        /**
0036         * This class represents a socket for sending and receiving datagram packets.
0037         *
0038         * <p>A datagram socket is the sending or receiving point for a packet
0039         * delivery service. Each packet sent or received on a datagram socket
0040         * is individually addressed and routed. Multiple packets sent from
0041         * one machine to another may be routed differently, and may arrive in
0042         * any order.
0043         *
0044         * <p>UDP broadcasts sends are always enabled on a DatagramSocket.
0045         * In order to receive broadcast packets a DatagramSocket
0046         * should be bound to the wildcard address. In some
0047         * implementations, broadcast packets may also be received when
0048         * a DatagramSocket is bound to a more specific address.
0049         * <p>
0050         * Example:
0051         * <code>
0052         *		DatagramSocket s = new DatagramSocket(null);
0053         *		s.bind(new InetSocketAddress(8888));
0054         * </code>
0055         * Which is equivalent to:
0056         * <code>
0057         *		DatagramSocket s = new DatagramSocket(8888);
0058         * </code>
0059         * Both cases will create a DatagramSocket able to receive broadcasts on
0060         * UDP port 8888.
0061         *
0062         * @author  Pavani Diwanji
0063         * @version 1.111, 06/11/07
0064         * @see     java.net.DatagramPacket
0065         * @see     java.nio.channels.DatagramChannel
0066         * @since JDK1.0
0067         */
0068        public class DatagramSocket implements  java.io.Closeable {
0069            /**
0070             * Various states of this socket.
0071             */
0072            private boolean created = false;
0073            private boolean bound = false;
0074            private boolean closed = false;
0075            private Object closeLock = new Object();
0076
0077            /*
0078             * The implementation of this DatagramSocket.
0079             */
0080            DatagramSocketImpl impl;
0081
0082            /**
0083             * Are we using an older DatagramSocketImpl?
0084             */
0085            boolean oldImpl = false;
0086
0087            /*
0088             * Connection state:
0089             * ST_NOT_CONNECTED = socket not connected
0090             * ST_CONNECTED = socket connected
0091             * ST_CONNECTED_NO_IMPL = socket connected but not at impl level
0092             */
0093            static final int ST_NOT_CONNECTED = 0;
0094            static final int ST_CONNECTED = 1;
0095            static final int ST_CONNECTED_NO_IMPL = 2;
0096
0097            int connectState = ST_NOT_CONNECTED;
0098
0099            /*
0100             * Connected address & port
0101             */
0102            InetAddress connectedAddress = null;
0103            int connectedPort = -1;
0104
0105            /**
0106             * Connects this socket to a remote socket address (IP address + port number).
0107             * Binds socket if not already bound.
0108             * <p>
0109             * @param   addr    The remote address.
0110             * @param	port	The remote port
0111             * @throws  SocketException if binding the socket fails.
0112             */
0113            private synchronized void connectInternal(InetAddress address,
0114                    int port) throws SocketException {
0115                if (port < 0 || port > 0xFFFF) {
0116                    throw new IllegalArgumentException("connect: " + port);
0117                }
0118                if (address == null) {
0119                    throw new IllegalArgumentException("connect: null address");
0120                }
0121                if (isClosed())
0122                    return;
0123                SecurityManager security = System.getSecurityManager();
0124                if (security != null) {
0125                    if (address.isMulticastAddress()) {
0126                        security.checkMulticast(address);
0127                    } else {
0128                        security.checkConnect(address.getHostAddress(), port);
0129                        security.checkAccept(address.getHostAddress(), port);
0130                    }
0131                }
0132
0133                if (!isBound())
0134                    bind(new InetSocketAddress(0));
0135
0136                // old impls do not support connect/disconnect
0137                if (oldImpl) {
0138                    connectState = ST_CONNECTED_NO_IMPL;
0139                } else {
0140                    try {
0141                        getImpl().connect(address, port);
0142
0143                        // socket is now connected by the impl
0144                        connectState = ST_CONNECTED;
0145                    } catch (SocketException se) {
0146
0147                        // connection will be emulated by DatagramSocket
0148                        connectState = ST_CONNECTED_NO_IMPL;
0149                    }
0150                }
0151
0152                connectedAddress = address;
0153                connectedPort = port;
0154            }
0155
0156            /**
0157             * Constructs a datagram socket and binds it to any available port
0158             * on the local host machine.  The socket will be bound to the 
0159             * {@link InetAddress#isAnyLocalAddress wildcard} address, 
0160             * an IP address chosen by the kernel.
0161             * 
0162             * <p>If there is a security manager, 
0163             * its <code>checkListen</code> method is first called
0164             * with 0 as its argument to ensure the operation is allowed. 
0165             * This could result in a SecurityException.
0166             *
0167             * @exception  SocketException  if the socket could not be opened,
0168             *               or the socket could not bind to the specified local port.
0169             * @exception  SecurityException  if a security manager exists and its  
0170             *             <code>checkListen</code> method doesn't allow the operation.
0171             * 
0172             * @see SecurityManager#checkListen
0173             */
0174            public DatagramSocket() throws SocketException {
0175                // create a datagram socket.
0176                createImpl();
0177                try {
0178                    bind(new InetSocketAddress(0));
0179                } catch (SocketException se) {
0180                    throw se;
0181                } catch (IOException e) {
0182                    throw new SocketException(e.getMessage());
0183                }
0184            }
0185
0186            /**
0187             * Creates an unbound datagram socket with the specified
0188             * DatagramSocketImpl.
0189             *
0190             * @param impl an instance of a <B>DatagramSocketImpl</B>
0191             *        the subclass wishes to use on the DatagramSocket.
0192             * @since   1.4
0193             */
0194            protected DatagramSocket(DatagramSocketImpl impl) {
0195                if (impl == null)
0196                    throw new NullPointerException();
0197                this .impl = impl;
0198                checkOldImpl();
0199            }
0200
0201            /**
0202             * Creates a datagram socket, bound to the specified local
0203             * socket address.
0204             * <p>
0205             * If, if the address is <code>null</code>, creates an unbound socket.
0206             * <p>
0207             * <p>If there is a security manager, 
0208             * its <code>checkListen</code> method is first called
0209             * with the port from the socket address
0210             * as its argument to ensure the operation is allowed. 
0211             * This could result in a SecurityException.
0212             * 
0213             * @param bindaddr local socket address to bind, or <code>null</code>
0214             *		       for an unbound socket.
0215             * 
0216             * @exception  SocketException  if the socket could not be opened,
0217             *               or the socket could not bind to the specified local port.
0218             * @exception  SecurityException  if a security manager exists and its  
0219             *             <code>checkListen</code> method doesn't allow the operation.
0220             * 
0221             * @see SecurityManager#checkListen
0222             * @since   1.4
0223             */
0224            public DatagramSocket(SocketAddress bindaddr)
0225                    throws SocketException {
0226                // create a datagram socket.
0227                createImpl();
0228                if (bindaddr != null) {
0229                    bind(bindaddr);
0230                }
0231            }
0232
0233            /**
0234             * Constructs a datagram socket and binds it to the specified port
0235             * on the local host machine.  The socket will be bound to the
0236             * {@link InetAddress#isAnyLocalAddress wildcard} address,
0237             * an IP address chosen by the kernel.
0238             * 
0239             * <p>If there is a security manager, 
0240             * its <code>checkListen</code> method is first called
0241             * with the <code>port</code> argument
0242             * as its argument to ensure the operation is allowed. 
0243             * This could result in a SecurityException.
0244             *
0245             * @param      port port to use.
0246             * @exception  SocketException  if the socket could not be opened,
0247             *               or the socket could not bind to the specified local port.
0248             * @exception  SecurityException  if a security manager exists and its  
0249             *             <code>checkListen</code> method doesn't allow the operation.
0250             * 
0251             * @see SecurityManager#checkListen
0252             */
0253            public DatagramSocket(int port) throws SocketException {
0254                this (port, null);
0255            }
0256
0257            /**
0258             * Creates a datagram socket, bound to the specified local
0259             * address.  The local port must be between 0 and 65535 inclusive.
0260             * If the IP address is 0.0.0.0, the socket will be bound to the
0261             * {@link InetAddress#isAnyLocalAddress wildcard} address,
0262             * an IP address chosen by the kernel.
0263             * 
0264             * <p>If there is a security manager, 
0265             * its <code>checkListen</code> method is first called
0266             * with the <code>port</code> argument
0267             * as its argument to ensure the operation is allowed. 
0268             * This could result in a SecurityException.
0269             * 
0270             * @param port local port to use
0271             * @param laddr local address to bind
0272             * 
0273             * @exception  SocketException  if the socket could not be opened,
0274             *               or the socket could not bind to the specified local port.
0275             * @exception  SecurityException  if a security manager exists and its  
0276             *             <code>checkListen</code> method doesn't allow the operation.
0277             * 
0278             * @see SecurityManager#checkListen
0279             * @since   JDK1.1
0280             */
0281            public DatagramSocket(int port, InetAddress laddr)
0282                    throws SocketException {
0283                this (new InetSocketAddress(laddr, port));
0284            }
0285
0286            private void checkOldImpl() {
0287                if (impl == null)
0288                    return;
0289                // DatagramSocketImpl.peekdata() is a protected method, therefore we need to use
0290                // getDeclaredMethod, therefore we need permission to access the member
0291                try {
0292                    AccessController
0293                            .doPrivileged(new PrivilegedExceptionAction() {
0294                                public Object run()
0295                                        throws NoSuchMethodException {
0296                                    Class[] cl = new Class[1];
0297                                    cl[0] = DatagramPacket.class;
0298                                    impl.getClass().getDeclaredMethod(
0299                                            "peekData", cl);
0300                                    return null;
0301                                }
0302                            });
0303                } catch (java.security.PrivilegedActionException e) {
0304                    oldImpl = true;
0305                }
0306            }
0307
0308            static Class implClass = null;
0309
0310            void createImpl() throws SocketException {
0311                if (impl == null) {
0312                    if (factory != null) {
0313                        impl = factory.createDatagramSocketImpl();
0314                        checkOldImpl();
0315                    } else {
0316                        boolean isMulticast = (this  instanceof  MulticastSocket) ? true
0317                                : false;
0318                        impl = DefaultDatagramSocketImplFactory
0319                                .createDatagramSocketImpl(isMulticast);
0320
0321                        checkOldImpl();
0322                    }
0323                }
0324                // creates a udp socket
0325                impl.create();
0326                created = true;
0327            }
0328
0329            /**
0330             * Get the <code>DatagramSocketImpl</code> attached to this socket, 
0331             * creating it if necessary.
0332             *
0333             * @return	the <code>DatagramSocketImpl</code> attached to that 
0334             * 		DatagramSocket
0335             * @throws SocketException if creation fails.
0336             * @since 1.4
0337             */
0338            DatagramSocketImpl getImpl() throws SocketException {
0339                if (!created)
0340                    createImpl();
0341                return impl;
0342            }
0343
0344            /**
0345             * Binds this DatagramSocket to a specific address & port.
0346             * <p>
0347             * If the address is <code>null</code>, then the system will pick up
0348             * an ephemeral port and a valid local address to bind the socket.
0349             *<p>
0350             * @param	addr The address & port to bind to.
0351             * @throws	SocketException if any error happens during the bind, or if the
0352             *		socket is already bound.
0353             * @throws	SecurityException  if a security manager exists and its  
0354             *             <code>checkListen</code> method doesn't allow the operation.
0355             * @throws IllegalArgumentException if addr is a SocketAddress subclass
0356             *         not supported by this socket.
0357             * @since 1.4
0358             */
0359            public synchronized void bind(SocketAddress addr)
0360                    throws SocketException {
0361                if (isClosed())
0362                    throw new SocketException("Socket is closed");
0363                if (isBound())
0364                    throw new SocketException("already bound");
0365                if (addr == null)
0366                    addr = new InetSocketAddress(0);
0367                if (!(addr instanceof  InetSocketAddress))
0368                    throw new IllegalArgumentException(
0369                            "Unsupported address type!");
0370                InetSocketAddress epoint = (InetSocketAddress) addr;
0371                if (epoint.isUnresolved())
0372                    throw new SocketException("Unresolved address");
0373                SecurityManager sec = System.getSecurityManager();
0374                if (sec != null) {
0375                    sec.checkListen(epoint.getPort());
0376                }
0377                try {
0378                    getImpl().bind(epoint.getPort(), epoint.getAddress());
0379                } catch (SocketException e) {
0380                    getImpl().close();
0381                    throw e;
0382                }
0383                bound = true;
0384            }
0385
0386            /** 
0387             * Connects the socket to a remote address for this socket. When a
0388             * socket is connected to a remote address, packets may only be
0389             * sent to or received from that address. By default a datagram
0390             * socket is not connected.
0391             *
0392             * <p>If the remote destination to which the socket is connected does not
0393             * exist, or is otherwise unreachable, and if an ICMP destination unreachable
0394             * packet has been received for that address, then a subsequent call to 
0395             * send or receive may throw a PortUnreachableException. Note, there is no 
0396             * guarantee that the exception will be thrown.
0397             *
0398             * <p>A caller's permission to send and receive datagrams to a
0399             * given host and port are checked at connect time. When a socket
0400             * is connected, receive and send <b>will not
0401             * perform any security checks</b> on incoming and outgoing
0402             * packets, other than matching the packet's and the socket's
0403             * address and port. On a send operation, if the packet's address
0404             * is set and the packet's address and the socket's address do not
0405             * match, an IllegalArgumentException will be thrown. A socket
0406             * connected to a multicast address may only be used to send packets.
0407             *
0408             * @param address the remote address for the socket
0409             *
0410             * @param port the remote port for the socket.
0411             *
0412             * @exception IllegalArgumentException if the address is null,
0413             * or the port is out of range.
0414             *
0415             * @exception SecurityException if the caller is not allowed to
0416             * send datagrams to and receive datagrams from the address and port.
0417             *
0418             * @see #disconnect
0419             * @see #send
0420             * @see #receive 
0421             */
0422            public void connect(InetAddress address, int port) {
0423                try {
0424                    connectInternal(address, port);
0425                } catch (SocketException se) {
0426                    throw new Error("connect failed", se);
0427                }
0428            }
0429
0430            /**
0431             * Connects this socket to a remote socket address (IP address + port number).
0432             * <p>
0433             * @param	addr	The remote address.
0434             * @throws	SocketException if the connect fails
0435             * @throws	IllegalArgumentException if addr is null or addr is a SocketAddress
0436             *		subclass not supported by this socket
0437             * @since 1.4
0438             * @see #connect
0439             */
0440            public void connect(SocketAddress addr) throws SocketException {
0441                if (addr == null)
0442                    throw new IllegalArgumentException("Address can't be null");
0443                if (!(addr instanceof  InetSocketAddress))
0444                    throw new IllegalArgumentException(
0445                            "Unsupported address type");
0446                InetSocketAddress epoint = (InetSocketAddress) addr;
0447                if (epoint.isUnresolved())
0448                    throw new SocketException("Unresolved address");
0449                connectInternal(epoint.getAddress(), epoint.getPort());
0450            }
0451
0452            /** 
0453             * Disconnects the socket. If the socket is closed or not connected,
0454             * then this method has no effect.
0455             *
0456             * @see #connect
0457             */
0458            public void disconnect() {
0459                synchronized (this ) {
0460                    if (isClosed())
0461                        return;
0462                    if (connectState == ST_CONNECTED) {
0463                        impl.disconnect();
0464                    }
0465                    connectedAddress = null;
0466                    connectedPort = -1;
0467                    connectState = ST_NOT_CONNECTED;
0468                }
0469            }
0470
0471            /**
0472             * Returns the binding state of the socket.
0473             * <p>
0474             * If the socket was bound prior to being {@link #close closed},
0475             * then this method will continue to return <code>true</code>
0476             * after the socket is closed.
0477             *
0478             * @return true if the socket successfully bound to an address
0479             * @since 1.4
0480             */
0481            public boolean isBound() {
0482                return bound;
0483            }
0484
0485            /**
0486             * Returns the connection state of the socket.
0487             * <p>
0488             * If the socket was connected prior to being {@link #close closed},
0489             * then this method will continue to return <code>true</code>
0490             * after the socket is closed.
0491             *
0492             * @return true if the socket successfully connected to a server
0493             * @since 1.4
0494             */
0495            public boolean isConnected() {
0496                return connectState != ST_NOT_CONNECTED;
0497            }
0498
0499            /**
0500             * Returns the address to which this socket is connected. Returns 
0501             * <code>null</code> if the socket is not connected.
0502             * <p>
0503             * If the socket was connected prior to being {@link #close closed},
0504             * then this method will continue to return the connected address 
0505             * after the socket is closed.
0506             *
0507             * @return the address to which this socket is connected.
0508             */
0509            public InetAddress getInetAddress() {
0510                return connectedAddress;
0511            }
0512
0513            /**
0514             * Returns the port number to which this socket is connected. 
0515             * Returns <code>-1</code> if the socket is not connected.
0516             * <p>
0517             * If the socket was connected prior to being {@link #close closed},
0518             * then this method will continue to return the connected port number
0519             * after the socket is closed.
0520             *
0521             * @return the port number to which this socket is connected.
0522             */
0523            public int getPort() {
0524                return connectedPort;
0525            }
0526
0527            /**
0528             * Returns the address of the endpoint this socket is connected to, or
0529             * <code>null</code> if it is unconnected.
0530             * <p>
0531             * If the socket was connected prior to being {@link #close closed},
0532             * then this method will continue to return the connected address
0533             * after the socket is closed.
0534             *
0535             * @return a <code>SocketAddress</code> representing the remote
0536             *         endpoint of this socket, or <code>null</code> if it is
0537             *         not connected yet.
0538             * @see #getInetAddress()
0539             * @see #getPort()
0540             * @see #connect(SocketAddress)
0541             * @since 1.4
0542             */
0543            public SocketAddress getRemoteSocketAddress() {
0544                if (!isConnected())
0545                    return null;
0546                return new InetSocketAddress(getInetAddress(), getPort());
0547            }
0548
0549            /**
0550             * Returns the address of the endpoint this socket is bound to.
0551             * 
0552             * @return a <code>SocketAddress</code> representing the local endpoint of this
0553             *	       socket, or <code>null</code> if it is closed or not bound yet.
0554             * @see #getLocalAddress()
0555             * @see #getLocalPort()
0556             * @see #bind(SocketAddress)
0557             * @since 1.4
0558             */
0559
0560            public SocketAddress getLocalSocketAddress() {
0561                if (isClosed())
0562                    return null;
0563                if (!isBound())
0564                    return null;
0565                return new InetSocketAddress(getLocalAddress(), getLocalPort());
0566            }
0567
0568            /**
0569             * Sends a datagram packet from this socket. The
0570             * <code>DatagramPacket</code> includes information indicating the
0571             * data to be sent, its length, the IP address of the remote host,
0572             * and the port number on the remote host.
0573             *
0574             * <p>If there is a security manager, and the socket is not currently
0575             * connected to a remote address, this method first performs some
0576             * security checks. First, if <code>p.getAddress().isMulticastAddress()</code>
0577             * is true, this method calls the
0578             * security manager's <code>checkMulticast</code> method
0579             * with <code>p.getAddress()</code> as its argument.
0580             * If the evaluation of that expression is false,
0581             * this method instead calls the security manager's 
0582             * <code>checkConnect</code> method with arguments
0583             * <code>p.getAddress().getHostAddress()</code> and
0584             * <code>p.getPort()</code>. Each call to a security manager method
0585             * could result in a SecurityException if the operation is not allowed.
0586             * 
0587             * @param      p   the <code>DatagramPacket</code> to be sent.
0588             * 
0589             * @exception  IOException  if an I/O error occurs.
0590             * @exception  SecurityException  if a security manager exists and its  
0591             *             <code>checkMulticast</code> or <code>checkConnect</code> 
0592             *             method doesn't allow the send.
0593             * @exception  PortUnreachableException may be thrown if the socket is connected
0594             *             to a currently unreachable destination. Note, there is no 
0595             * 		   guarantee that the exception will be thrown.
0596             * @exception  java.nio.channels.IllegalBlockingModeException
0597             *             if this socket has an associated channel,
0598             *             and the channel is in non-blocking mode.
0599             * @exception  IllegalArgumentException if the socket is connected,
0600             *             and connected address and packet address differ.
0601             * 
0602             * @see        java.net.DatagramPacket
0603             * @see        SecurityManager#checkMulticast(InetAddress)
0604             * @see        SecurityManager#checkConnect
0605             * @revised 1.4
0606             * @spec JSR-51
0607             */
0608            public void send(DatagramPacket p) throws IOException {
0609                InetAddress packetAddress = null;
0610                synchronized (p) {
0611                    if (isClosed())
0612                        throw new SocketException("Socket is closed");
0613                    if (connectState == ST_NOT_CONNECTED) {
0614                        // check the address is ok wiht the security manager on every send.
0615                        SecurityManager security = System.getSecurityManager();
0616
0617                        // The reason you want to synchronize on datagram packet
0618                        // is because you dont want an applet to change the address 
0619                        // while you are trying to send the packet for example 
0620                        // after the security check but before the send.
0621                        if (security != null) {
0622                            if (p.getAddress().isMulticastAddress()) {
0623                                security.checkMulticast(p.getAddress());
0624                            } else {
0625                                security.checkConnect(p.getAddress()
0626                                        .getHostAddress(), p.getPort());
0627                            }
0628                        }
0629                    } else {
0630                        // we're connected
0631                        packetAddress = p.getAddress();
0632                        if (packetAddress == null) {
0633                            p.setAddress(connectedAddress);
0634                            p.setPort(connectedPort);
0635                        } else if ((!packetAddress.equals(connectedAddress))
0636                                || p.getPort() != connectedPort) {
0637                            throw new IllegalArgumentException(
0638                                    "connected address " + "and packet address"
0639                                            + " differ");
0640                        }
0641                    }
0642                    // Check whether the socket is bound
0643                    if (!isBound())
0644                        bind(new InetSocketAddress(0));
0645                    // call the  method to send
0646                    getImpl().send(p);
0647                }
0648            }
0649
0650            /**
0651             * Receives a datagram packet from this socket. When this method
0652             * returns, the <code>DatagramPacket</code>'s buffer is filled with
0653             * the data received. The datagram packet also contains the sender's
0654             * IP address, and the port number on the sender's machine.
0655             * <p>
0656             * This method blocks until a datagram is received. The
0657             * <code>length</code> field of the datagram packet object contains
0658             * the length of the received message. If the message is longer than
0659             * the packet's length, the message is truncated.
0660             * <p>
0661             * If there is a security manager, a packet cannot be received if the
0662             * security manager's <code>checkAccept</code> method
0663             * does not allow it.
0664             * 
0665             * @param      p   the <code>DatagramPacket</code> into which to place
0666             *                 the incoming data.
0667             * @exception  IOException  if an I/O error occurs.
0668             * @exception  SocketTimeoutException  if setSoTimeout was previously called
0669             *		       and the timeout has expired.
0670             * @exception  PortUnreachableException may be thrown if the socket is connected
0671             *       	   to a currently unreachable destination. Note, there is no guarantee that the
0672             *       	   exception will be thrown.
0673             * @exception  java.nio.channels.IllegalBlockingModeException
0674             *             if this socket has an associated channel,
0675             *             and the channel is in non-blocking mode.
0676             * @see        java.net.DatagramPacket
0677             * @see        java.net.DatagramSocket
0678             * @revised 1.4
0679             * @spec JSR-51
0680             */
0681            public synchronized void receive(DatagramPacket p)
0682                    throws IOException {
0683                synchronized (p) {
0684                    if (!isBound())
0685                        bind(new InetSocketAddress(0));
0686                    if (connectState == ST_NOT_CONNECTED) {
0687                        // check the address is ok with the security manager before every recv.
0688                        SecurityManager security = System.getSecurityManager();
0689                        if (security != null) {
0690                            while (true) {
0691                                String peekAd = null;
0692                                int peekPort = 0;
0693                                // peek at the packet to see who it is from.
0694                                if (!oldImpl) {
0695                                    // We can use the new peekData() API
0696                                    DatagramPacket peekPacket = new DatagramPacket(
0697                                            new byte[1], 1);
0698                                    peekPort = getImpl().peekData(peekPacket);
0699                                    peekAd = peekPacket.getAddress()
0700                                            .getHostAddress();
0701                                } else {
0702                                    InetAddress adr = new InetAddress();
0703                                    peekPort = getImpl().peek(adr);
0704                                    peekAd = adr.getHostAddress();
0705                                }
0706                                try {
0707                                    security.checkAccept(peekAd, peekPort);
0708                                    // security check succeeded - so now break
0709                                    // and recv the packet.
0710                                    break;
0711                                } catch (SecurityException se) {
0712                                    // Throw away the offending packet by consuming
0713                                    // it in a tmp buffer.
0714                                    DatagramPacket tmp = new DatagramPacket(
0715                                            new byte[1], 1);
0716                                    getImpl().receive(tmp);
0717
0718                                    // silently discard the offending packet
0719                                    // and continue: unknown/malicious
0720                                    // entities on nets should not make
0721                                    // runtime throw security exception and
0722                                    // disrupt the applet by sending random
0723                                    // datagram packets.
0724                                    continue;
0725                                }
0726                            } // end of while
0727                        }
0728                    }
0729                    if (connectState == ST_CONNECTED_NO_IMPL) {
0730                        // We have to do the filtering the old fashioned way since
0731                        // the native impl doesn't support connect or the connect
0732                        // via the impl failed.
0733                        boolean stop = false;
0734                        while (!stop) {
0735                            // peek at the packet to see who it is from.
0736                            InetAddress peekAddress = new InetAddress();
0737                            int peekPort = getImpl().peek(peekAddress);
0738                            if ((!connectedAddress.equals(peekAddress))
0739                                    || (connectedPort != peekPort)) {
0740                                // throw the packet away and silently continue
0741                                DatagramPacket tmp = new DatagramPacket(
0742                                        new byte[1], 1);
0743                                getImpl().receive(tmp);
0744                            } else {
0745                                stop = true;
0746                            }
0747                        }
0748                    }
0749                    // If the security check succeeds, or the datagram is
0750                    // connected then receive the packet
0751                    getImpl().receive(p);
0752                }
0753            }
0754
0755            /**
0756             * Gets the local address to which the socket is bound.
0757             *
0758             * <p>If there is a security manager, its
0759             * <code>checkConnect</code> method is first called
0760             * with the host address and <code>-1</code>
0761             * as its arguments to see if the operation is allowed.
0762             *
0763             * @see SecurityManager#checkConnect
0764             * @return  the local address to which the socket is bound, 
0765             *          <code>null</code> if the socket is closed, or
0766             *		an <code>InetAddress</code> representing 
0767             *          {@link InetAddress#isAnyLocalAddress wildcard}
0768             *		address if either the socket is not bound, or
0769             *		the security manager <code>checkConnect</code>
0770             *		method does not allow the operation
0771             * @since   1.1
0772             */
0773            public InetAddress getLocalAddress() {
0774                if (isClosed())
0775                    return null;
0776                InetAddress in = null;
0777                try {
0778                    in = (InetAddress) getImpl().getOption(
0779                            SocketOptions.SO_BINDADDR);
0780                    if (in.isAnyLocalAddress()) {
0781                        in = InetAddress.anyLocalAddress();
0782                    }
0783                    SecurityManager s = System.getSecurityManager();
0784                    if (s != null) {
0785                        s.checkConnect(in.getHostAddress(), -1);
0786                    }
0787                } catch (Exception e) {
0788                    in = InetAddress.anyLocalAddress(); // "0.0.0.0"
0789                }
0790                return in;
0791            }
0792
0793            /**
0794             * Returns the port number on the local host to which this socket
0795             * is bound.
0796             *
0797             * @return  the port number on the local host to which this socket is bound,
0798            	<code>-1</code> if the socket is closed, or
0799            	<code>0</code> if it is not bound yet.
0800             */
0801            public int getLocalPort() {
0802                if (isClosed())
0803                    return -1;
0804                try {
0805                    return getImpl().getLocalPort();
0806                } catch (Exception e) {
0807                    return 0;
0808                }
0809            }
0810
0811            /** Enable/disable SO_TIMEOUT with the specified timeout, in
0812             *  milliseconds. With this option set to a non-zero timeout,
0813             *  a call to receive() for this DatagramSocket
0814             *  will block for only this amount of time.  If the timeout expires,
0815             *  a <B>java.net.SocketTimeoutException</B> is raised, though the
0816             *  DatagramSocket is still valid.  The option <B>must</B> be enabled
0817             *  prior to entering the blocking operation to have effect.  The
0818             *  timeout must be > 0.
0819             *  A timeout of zero is interpreted as an infinite timeout.
0820             *
0821             * @param timeout the specified timeout in milliseconds.
0822             * @throws SocketException if there is an error in the underlying protocol, such as an UDP error. 
0823             * @since   JDK1.1
0824             * @see #getSoTimeout()
0825             */
0826            public synchronized void setSoTimeout(int timeout)
0827                    throws SocketException {
0828                if (isClosed())
0829                    throw new SocketException("Socket is closed");
0830                getImpl().setOption(SocketOptions.SO_TIMEOUT,
0831                        new Integer(timeout));
0832            }
0833
0834            /**
0835             * Retrieve setting for SO_TIMEOUT.  0 returns implies that the
0836             * option is disabled (i.e., timeout of infinity).
0837             *
0838             * @return the setting for SO_TIMEOUT
0839             * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
0840             * @since   JDK1.1
0841             * @see #setSoTimeout(int)
0842             */
0843            public synchronized int getSoTimeout() throws SocketException {
0844                if (isClosed())
0845                    throw new SocketException("Socket is closed");
0846                if (getImpl() == null)
0847                    return 0;
0848                Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
0849                /* extra type safety */
0850                if (o instanceof  Integer) {
0851                    return ((Integer) o).intValue();
0852                } else {
0853                    return 0;
0854                }
0855            }
0856
0857            /**
0858             * Sets the SO_SNDBUF option to the specified value for this
0859             * <tt>DatagramSocket</tt>. The SO_SNDBUF option is used by the 
0860             * network implementation as a hint to size the underlying
0861             * network I/O buffers. The SO_SNDBUF setting may also be used 
0862             * by the network implementation to determine the maximum size
0863             * of the packet that can be sent on this socket.
0864             * <p>
0865             * As SO_SNDBUF is a hint, applications that want to verify
0866             * what size the buffer is should call {@link #getSendBufferSize()}.
0867             * <p>
0868             * Increasing the buffer size may allow multiple outgoing packets 
0869             * to be queued by the network implementation when the send rate
0870             * is high. 
0871             * <p>
0872             * Note: If {@link #send(DatagramPacket)} is used to send a 
0873             * <code>DatagramPacket</code> that is larger than the setting
0874             * of SO_SNDBUF then it is implementation specific if the
0875             * packet is sent or discarded.
0876             *
0877             * @param size the size to which to set the send buffer
0878             * size. This value must be greater than 0.
0879             *
0880             * @exception SocketException if there is an error 
0881             * in the underlying protocol, such as an UDP error.
0882             * @exception IllegalArgumentException if the value is 0 or is
0883             * negative.
0884             * @see #getSendBufferSize()
0885             */
0886            public synchronized void setSendBufferSize(int size)
0887                    throws SocketException {
0888                if (!(size > 0)) {
0889                    throw new IllegalArgumentException("negative send size");
0890                }
0891                if (isClosed())
0892                    throw new SocketException("Socket is closed");
0893                getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
0894            }
0895
0896            /**
0897             * Get value of the SO_SNDBUF option for this <tt>DatagramSocket</tt>, that is the
0898             * buffer size used by the platform for output on this <tt>DatagramSocket</tt>.
0899             *
0900             * @return the value of the SO_SNDBUF option for this <tt>DatagramSocket</tt>
0901             * @exception SocketException if there is an error in 
0902             * the underlying protocol, such as an UDP error.
0903             * @see #setSendBufferSize
0904             */
0905            public synchronized int getSendBufferSize() throws SocketException {
0906                if (isClosed())
0907                    throw new SocketException("Socket is closed");
0908                int result = 0;
0909                Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
0910                if (o instanceof  Integer) {
0911                    result = ((Integer) o).intValue();
0912                }
0913                return result;
0914            }
0915
0916            /**
0917             * Sets the SO_RCVBUF option to the specified value for this
0918             * <tt>DatagramSocket</tt>. The SO_RCVBUF option is used by the
0919             * the network implementation as a hint to size the underlying
0920             * network I/O buffers. The SO_RCVBUF setting may also be used
0921             * by the network implementation to determine the maximum size
0922             * of the packet that can be received on this socket.
0923             * <p>
0924             * Because SO_RCVBUF is a hint, applications that want to
0925             * verify what size the buffers were set to should call
0926             * {@link #getReceiveBufferSize()}.
0927             * <p>
0928             * Increasing SO_RCVBUF may allow the network implementation
0929             * to buffer multiple packets when packets arrive faster than
0930             * are being received using {@link #receive(DatagramPacket)}.
0931             * <p>
0932             * Note: It is implementation specific if a packet larger
0933             * than SO_RCVBUF can be received.
0934             *
0935             * @param size the size to which to set the receive buffer
0936             * size. This value must be greater than 0.
0937             *
0938             * @exception SocketException if there is an error in 
0939             * the underlying protocol, such as an UDP error.
0940             * @exception IllegalArgumentException if the value is 0 or is
0941             * negative.
0942             * @see #getReceiveBufferSize()
0943             */
0944            public synchronized void setReceiveBufferSize(int size)
0945                    throws SocketException {
0946                if (size <= 0) {
0947                    throw new IllegalArgumentException("invalid receive size");
0948                }
0949                if (isClosed())
0950                    throw new SocketException("Socket is closed");
0951                getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
0952            }
0953
0954            /**
0955             * Get value of the SO_RCVBUF option for this <tt>DatagramSocket</tt>, that is the
0956             * buffer size used by the platform for input on this <tt>DatagramSocket</tt>.
0957             *
0958             * @return the value of the SO_RCVBUF option for this <tt>DatagramSocket</tt>
0959             * @exception SocketException if there is an error in the underlying protocol, such as an UDP error.
0960             * @see #setReceiveBufferSize(int)
0961             */
0962            public synchronized int getReceiveBufferSize()
0963                    throws SocketException {
0964                if (isClosed())
0965                    throw new SocketException("Socket is closed");
0966                int result = 0;
0967                Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
0968                if (o instanceof  Integer) {
0969                    result = ((Integer) o).intValue();
0970                }
0971                return result;
0972            }
0973
0974            /**
0975             * Enable/disable the SO_REUSEADDR socket option.
0976             * <p>
0977             * For UDP sockets it may be necessary to bind more than one
0978             * socket to the same socket address. This is typically for the
0979             * purpose of receiving multicast packets
0980             * (See {@link java.net.MulticastSocket}). The
0981             * <tt>SO_REUSEADDR</tt> socket option allows multiple
0982             * sockets to be bound to the same socket address if the
0983             * <tt>SO_REUSEADDR</tt> socket option is enabled prior
0984             * to binding the socket using {@link #bind(SocketAddress)}.
0985             * <p>
0986             * Note: This functionality is not supported by all existing platforms,
0987             * so it is implementation specific whether this option will be ignored
0988             * or not. However, if it is not supported then
0989             * {@link #getReuseAddress()} will always return <code>false</code>.
0990             * <p>
0991             * When a <tt>DatagramSocket</tt> is created the initial setting
0992             * of <tt>SO_REUSEADDR</tt> is disabled.
0993             * <p>
0994             * The behaviour when <tt>SO_REUSEADDR</tt> is enabled or
0995             * disabled after a socket is bound (See {@link #isBound()})
0996             * is not defined.
0997             * 
0998             * @param on  whether to enable or disable the 
0999             * @exception SocketException if an error occurs enabling or
1000             *            disabling the <tt>SO_RESUEADDR</tt> socket option,
1001             *	   	  or the socket is closed.
1002             * @since 1.4
1003             * @see #getReuseAddress()     
1004             * @see #bind(SocketAddress)     
1005             * @see #isBound()
1006             * @see #isClosed()
1007             */
1008            public synchronized void setReuseAddress(boolean on)
1009                    throws SocketException {
1010                if (isClosed())
1011                    throw new SocketException("Socket is closed");
1012                // Integer instead of Boolean for compatibility with older DatagramSocketImpl
1013                if (oldImpl)
1014                    getImpl().setOption(SocketOptions.SO_REUSEADDR,
1015                            new Integer(on ? -1 : 0));
1016                else
1017                    getImpl().setOption(SocketOptions.SO_REUSEADDR,
1018                            Boolean.valueOf(on));
1019            }
1020
1021            /**
1022             * Tests if SO_REUSEADDR is enabled.
1023             *
1024             * @return a <code>boolean</code> indicating whether or not SO_REUSEADDR is enabled.
1025             * @exception SocketException if there is an error
1026             * in the underlying protocol, such as an UDP error. 
1027             * @since   1.4
1028             * @see #setReuseAddress(boolean)
1029             */
1030            public synchronized boolean getReuseAddress()
1031                    throws SocketException {
1032                if (isClosed())
1033                    throw new SocketException("Socket is closed");
1034                Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR);
1035                return ((Boolean) o).booleanValue();
1036            }
1037
1038            /**
1039             * Enable/disable SO_BROADCAST.
1040             * @param on     whether or not to have broadcast turned on.
1041             * @exception SocketException if there is an error
1042             * in the underlying protocol, such as an UDP error.
1043             * @since 1.4
1044             * @see #getBroadcast()
1045             */
1046            public synchronized void setBroadcast(boolean on)
1047                    throws SocketException {
1048                if (isClosed())
1049                    throw new SocketException("Socket is closed");
1050                getImpl().setOption(SocketOptions.SO_BROADCAST,
1051                        Boolean.valueOf(on));
1052            }
1053
1054            /**
1055             * Tests if SO_BROADCAST is enabled.
1056             * @return a <code>boolean</code> indicating whether or not SO_BROADCAST is enabled.
1057             * @exception SocketException if there is an error
1058             * in the underlying protocol, such as an UDP error.
1059             * @since 1.4
1060             * @see #setBroadcast(boolean)
1061             */
1062            public synchronized boolean getBroadcast() throws SocketException {
1063                if (isClosed())
1064                    throw new SocketException("Socket is closed");
1065                return ((Boolean) (getImpl()
1066                        .getOption(SocketOptions.SO_BROADCAST))).booleanValue();
1067            }
1068
1069            /**
1070             * Sets traffic class or type-of-service octet in the IP
1071             * datagram header for datagrams sent from this DatagramSocket.
1072             * As the underlying network implementation may ignore this
1073             * value applications should consider it a hint.
1074             *
1075             * <P> The tc <B>must</B> be in the range <code> 0 <= tc <=
1076             * 255</code> or an IllegalArgumentException will be thrown.
1077             * <p>Notes:
1078             * <p>For Internet Protocol v4 the value consists of an 
1079             * <code>integer</code>, the least significant 8 bits of which
1080             * represent the value of the TOS octet in IP packets sent by
1081             * the socket.
1082             * RFC 1349 defines the TOS values as follows:
1083             * <p>
1084             * <UL>
1085             * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
1086             * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
1087             * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
1088             * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
1089             * </UL>
1090             * The last low order bit is always ignored as this
1091             * corresponds to the MBZ (must be zero) bit.
1092             * <p>
1093             * Setting bits in the precedence field may result in a 
1094             * SocketException indicating that the operation is not
1095             * permitted.
1096             * <p>
1097             * for Internet Protocol v6 <code>tc</code> is the value that 
1098             * would be placed into the sin6_flowinfo field of the IP header.
1099             *
1100             * @param tc	an <code>int</code> value for the bitset.
1101             * @throws SocketException if there is an error setting the
1102             * traffic class or type-of-service 
1103             * @since 1.4
1104             * @see #getTrafficClass
1105             */
1106            public synchronized void setTrafficClass(int tc)
1107                    throws SocketException {
1108                if (tc < 0 || tc > 255)
1109                    throw new IllegalArgumentException(
1110                            "tc is not in range 0 -- 255");
1111
1112                if (isClosed())
1113                    throw new SocketException("Socket is closed");
1114                getImpl().setOption(SocketOptions.IP_TOS, new Integer(tc));
1115            }
1116
1117            /**
1118             * Gets traffic class or type-of-service in the IP datagram 
1119             * header for packets sent from this DatagramSocket.
1120             * <p>
1121             * As the underlying network implementation may ignore the
1122             * traffic class or type-of-service set using {@link #setTrafficClass(int)}
1123             * this method may return a different value than was previously
1124             * set using the {@link #setTrafficClass(int)} method on this 
1125             * DatagramSocket.
1126             *
1127             * @return the traffic class or type-of-service already set
1128             * @throws SocketException if there is an error obtaining the
1129             * traffic class or type-of-service value.
1130             * @since 1.4
1131             * @see #setTrafficClass(int)
1132             */
1133            public synchronized int getTrafficClass() throws SocketException {
1134                if (isClosed())
1135                    throw new SocketException("Socket is closed");
1136                return ((Integer) (getImpl().getOption(SocketOptions.IP_TOS)))
1137                        .intValue();
1138            }
1139
1140            /**
1141             * Closes this datagram socket.
1142             * <p>
1143             * Any thread currently blocked in {@link #receive} upon this socket
1144             * will throw a {@link SocketException}.
1145             *
1146             * <p> If this socket has an associated channel then the channel is closed
1147             * as well.
1148             *
1149             * @revised 1.4
1150             * @spec JSR-51
1151             */
1152            public void close() {
1153                synchronized (closeLock) {
1154                    if (isClosed())
1155                        return;
1156                    impl.close();
1157                    closed = true;
1158                }
1159            }
1160
1161            /**
1162             * Returns whether the socket is closed or not.
1163             *
1164             * @return true if the socket has been closed
1165             * @since 1.4
1166             */
1167            public boolean isClosed() {
1168                synchronized (closeLock) {
1169                    return closed;
1170                }
1171            }
1172
1173            /**
1174             * Returns the unique {@link java.nio.channels.DatagramChannel} object
1175             * associated with this datagram socket, if any.
1176             *
1177             * <p> A datagram socket will have a channel if, and only if, the channel
1178             * itself was created via the {@link java.nio.channels.DatagramChannel#open
1179             * DatagramChannel.open} method.
1180             *
1181             * @return  the datagram channel associated with this datagram socket,
1182             *          or <tt>null</tt> if this socket was not created for a channel
1183             *
1184             * @since 1.4
1185             * @spec JSR-51
1186             */
1187            public DatagramChannel getChannel() {
1188                return null;
1189            }
1190
1191            /**
1192             * User defined factory for all datagram sockets.
1193             */
1194            static DatagramSocketImplFactory factory;
1195
1196            /**
1197             * Sets the datagram socket implementation factory for the
1198             * application. The factory can be specified only once.
1199             * <p>
1200             * When an application creates a new datagram socket, the socket
1201             * implementation factory's <code>createDatagramSocketImpl</code> method is
1202             * called to create the actual datagram socket implementation.
1203             * <p>
1204             * Passing <code>null</code> to the method is a no-op unless the factory
1205             * was already set.
1206             * 
1207             * <p>If there is a security manager, this method first calls
1208             * the security manager's <code>checkSetFactory</code> method 
1209             * to ensure the operation is allowed. 
1210             * This could result in a SecurityException.
1211             *
1212             * @param      fac   the desired factory.
1213             * @exception  IOException  if an I/O error occurs when setting the
1214             *              datagram socket factory.
1215             * @exception  SocketException  if the factory is already defined.
1216             * @exception  SecurityException  if a security manager exists and its  
1217             *             <code>checkSetFactory</code> method doesn't allow the 
1218             operation.
1219             * @see        
1220             java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
1221             * @see       SecurityManager#checkSetFactory
1222             * @since 1.3
1223             */
1224            public static synchronized void setDatagramSocketImplFactory(
1225                    DatagramSocketImplFactory fac) throws IOException {
1226                if (factory != null) {
1227                    throw new SocketException("factory already defined");
1228                }
1229                SecurityManager security = System.getSecurityManager();
1230                if (security != null) {
1231                    security.checkSetFactory();
1232                }
1233                factory = fac;
1234            }
1235        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.