FileDocCategorySizeDatePackage
DatagramSocket.javaAPI DocAndroid 1.5 API31626Wed May 06 22:41:04 BST 2009java.net

DatagramSocket

public class DatagramSocket extends Object
This class implements a UDP socket for sending and receiving {@code DatagramPacket}. A {@code DatagramSocket} object can be used for both endpoints of a connection for a packet delivery service.
see
DatagramPacket
see
DatagramSocketImplFactory
since
Android 1.0

Fields Summary
DatagramSocketImpl
impl
InetAddress
address
int
port
static DatagramSocketImplFactory
factory
boolean
isBound
private boolean
isConnected
private boolean
isClosed
private Object
lock
Constructors Summary
public DatagramSocket()
Constructs a UDP datagram socket which is bound to any available port on the localhost.

throws
SocketException if an error occurs while creating or binding the socket.
since
Android 1.0


                                                    
        
        this(0);
    
public DatagramSocket(int aPort)
Constructs a UDP datagram socket which is bound to the specific port {@code aPort} on the localhost. Valid values for {@code aPort} are between 0 and 65535 inclusive.

param
aPort the port to bind on the localhost.
throws
SocketException if an error occurs while creating or binding the socket.
since
Android 1.0

        super();
        checkListen(aPort);
        createSocket(aPort, InetAddress.ANY);
    
protected DatagramSocket(DatagramSocketImpl socketImpl)
Constructs a new {@code DatagramSocket} using the specific datagram socket implementation {@code socketImpl}. The created {@code DatagramSocket} will not be bound.

param
socketImpl the DatagramSocketImpl to use.
since
Android 1.0

        if (socketImpl == null) {
            throw new NullPointerException();
        }
        impl = socketImpl;
    
public DatagramSocket(SocketAddress localAddr)
Constructs a new {@code DatagramSocket} bound to the host/port specified by the {@code SocketAddress} {@code localAddr} or an unbound {@code DatagramSocket} if the {@code SocketAddress} is {@code null}.

param
localAddr the local machine address and port to bind to.
throws
SocketException if a problem occurs creating or binding the socket.
since
Android 1.0

        if (localAddr != null) {
            if (!(localAddr instanceof InetSocketAddress)) {
                throw new IllegalArgumentException(Msg.getString(
                        "K0316", localAddr.getClass())); //$NON-NLS-1$
            }
            checkListen(((InetSocketAddress) localAddr).getPort());
        }
        impl = factory != null ? factory.createDatagramSocketImpl()
                : SocketImplProvider.getDatagramSocketImpl();
        impl.create();
        if (localAddr != null) {
            try {
                bind(localAddr);
            } catch (SocketException e) {
                close();
                throw e;
            }
        }
        // SocketOptions.SO_BROADCAST is set by default for DatagramSocket
        setBroadcast(true);
    
public DatagramSocket(int aPort, InetAddress addr)
Constructs a UDP datagram socket which is bound to the specific local address {@code addr} on port {@code aPort}. Valid values for {@code aPort} are between 0 and 65535 inclusive.

param
aPort the port to bind on the localhost.
param
addr the address to bind on the localhost.
throws
SocketException if an error occurs while creating or binding the socket.
since
Android 1.0

        super();
        checkListen(aPort);
        createSocket(aPort, null == addr ? InetAddress.ANY : addr);
    
Methods Summary
public voidbind(java.net.SocketAddress localAddr)
Binds this socket to the local address and port specified by {@code localAddr}. If this value is {@code null} any free port on a valid local address is used.

param
localAddr the local machine address and port to bind on.
throws
SocketException if the socket is already bound or a problem occurs during binding.
since
Android 1.0

        checkClosedAndBind(false);
        int localPort = 0;
        InetAddress addr = InetAddress.ANY;
        if (localAddr != null) {
            if (!(localAddr instanceof InetSocketAddress)) {
                throw new IllegalArgumentException(Msg.getString(
                        "K0316", localAddr.getClass())); //$NON-NLS-1$
            }
            InetSocketAddress inetAddr = (InetSocketAddress) localAddr;
            addr = inetAddr.getAddress();
            if (addr == null) {
                throw new SocketException(Msg.getString(
                        "K0317", inetAddr.getHostName())); //$NON-NLS-1$
            }
            localPort = inetAddr.getPort();
            checkListen(localPort);
        }
        impl.bind(localPort, addr);
        isBound = true;
    
voidcheckClosedAndBind(boolean bind)

        if (isClosed()) {
            throw new SocketException(Msg.getString("K003d")); //$NON-NLS-1$
        }
        if (bind && !isBound()) {
            checkListen(0);
            impl.bind(0, InetAddress.ANY);
            isBound = true;
        }
    
voidcheckListen(int aPort)
Sends prior to attempting to bind the socket, checks whether the port is within the valid port range and verifies with the security manager that the port may be bound by the current context.

param
aPort the port on the localhost that is to be bound.
since
Android 1.0

        if (aPort < 0 || aPort > 65535) {
            throw new IllegalArgumentException(Msg.getString("K0325", aPort)); //$NON-NLS-1$
        }
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkListen(aPort);
        }
    
public voidclose()
Closes this UDP datagram socket and all possibly associated channels.

since
Android 1.0

        isClosed = true;
        impl.close();
    
public voidconnect(java.net.SocketAddress remoteAddr)
Connects this datagram socket to the remote host and port specified by {@code remoteAddr}. The host and port are validated, thereafter the only validation on {@code send()} and {@code receive()} is that the packet address/port matches the connected target.

param
remoteAddr the address and port of the target host.
exception
SocketException if an error occurs during connecting.
since
Android 1.0

        if (remoteAddr == null) {
            throw new IllegalArgumentException(Msg.getString("K0318")); //$NON-NLS-1$
        }

        if (!(remoteAddr instanceof InetSocketAddress)) {
            throw new IllegalArgumentException(Msg.getString(
                    "K0316", remoteAddr.getClass())); //$NON-NLS-1$
        }

        InetSocketAddress inetAddr = (InetSocketAddress) remoteAddr;
        if (inetAddr.getAddress() == null) {
            throw new SocketException(Msg.getString(
                    "K0317", inetAddr.getHostName())); //$NON-NLS-1$
        }

        synchronized (lock) {
            // make sure the socket is open
            checkClosedAndBind(true);

            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                if (inetAddr.getAddress().isMulticastAddress()) {
                    security.checkMulticast(inetAddr.getAddress());
                } else {
                    security.checkConnect(inetAddr.getAddress().getHostName(),
                            inetAddr.getPort());
                }
            }

            // now try to do the connection at the native level. To be
            // compatible for the case when the address is inaddr_any we just
            // eat the exception an act as if we are connected at the java level
            try {
                impl.connect(inetAddr.getAddress(), inetAddr.getPort());
            } catch (Exception e) {
                // not connected at the native level just do what we did before
            }

            // if we get here then we connected ok
            address = inetAddr.getAddress();
            port = inetAddr.getPort();
            isConnected = true;
        }
    
public voidconnect(java.net.InetAddress anAddress, int aPort)
Connects this UDP datagram socket to the specific target host with the address {@code anAdress} on port {@code aPort}. The host and port are validated, thereafter the only validation on {@code send()} and {@code receive()} is to check whether the packet address/port matches the connected target.

param
anAddress the target address of this socket.
param
aPort the target port of this socket.
since
Android 1.0

        if (anAddress == null || aPort < 0 || aPort > 65535) {
            throw new IllegalArgumentException(Msg.getString("K0032")); //$NON-NLS-1$
        }

        synchronized (lock) {
            if (isClosed()) {
                return;
            }
            try {
                checkClosedAndBind(true);
            } catch (SocketException e) {
                // Ignored
            }

            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                if (anAddress.isMulticastAddress()) {
                    security.checkMulticast(anAddress);
                } else {
                    security.checkConnect(anAddress.getHostName(), aPort);
                }
            }

            try {
                impl.connect(anAddress, aPort);
            } catch (SocketException e) {
                // not connected at the native level just do what we did before
            }
            address = anAddress;
            port = aPort;
            isConnected = true;
        }
    
synchronized voidcreateSocket(int aPort, java.net.InetAddress addr)

        impl = factory != null ? factory.createDatagramSocketImpl()
                : SocketImplProvider.getDatagramSocketImpl();
        impl.create();
        try {
            impl.bind(aPort, addr);
            isBound = true;
        } catch (SocketException e) {
            close();
            throw e;
        }
    
public voiddisconnect()
Disconnects this UDP datagram socket from the remote host. This method called on an unconnected socket does nothing.

since
Android 1.0

        if (isClosed() || !isConnected()) {
            return;
        }
        impl.disconnect();
        address = null;
        port = -1;
        isConnected = false;
    
public booleangetBroadcast()
Gets the state of the socket option {@code SocketOptions.SO_BROADCAST}.

return
{@code true} if the option is enabled, {@code false} otherwise.
throws
SocketException if the socket is closed or the option is invalid.
since
Android 1.0

        checkClosedAndBind(false);
        return ((Boolean) impl.getOption(SocketOptions.SO_BROADCAST))
                .booleanValue();
    
public java.nio.channels.DatagramChannelgetChannel()
Gets the related DatagramChannel of this socket. This implementation returns always {@code null}.

return
the related DatagramChannel or {@code null} if this socket was not created by a {@code DatagramChannel} object.
since
Android 1.0

        return null;
    
public java.net.InetAddressgetInetAddress()
Gets the {@code InetAddress} instance representing the remote address to which this UDP datagram socket is connected.

return
the remote address this socket is connected to or {@code null} if this socket is not connected.
since
Android 1.0

        return address;
    
public java.net.InetAddressgetLocalAddress()
Gets the {@code InetAddress} instance representing the bound local address of this UDP datagram socket.

return
the local address to which this socket is bound to or {@code null} if this socket is closed.
since
Android 1.0

        if (isClosed()) {
            return null;
        }
        if (!isBound()) {
            return InetAddress.ANY;
        }
        InetAddress anAddr = impl.getLocalAddress();
        try {
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkConnect(anAddr.getHostName(), -1);
            }
        } catch (SecurityException e) {
            return InetAddress.ANY;
        }
        return anAddr;
    
public intgetLocalPort()
Gets the local port which this socket is bound to.

return
the local port of this socket or {@code -1} if this socket is closed and {@code 0} if it is unbound.
since
Android 1.0

        if (isClosed()) {
            return -1;
        }
        if (!isBound()) {
            return 0;
        }
        return impl.getLocalPort();
    
public java.net.SocketAddressgetLocalSocketAddress()
Gets the bound local address and port of this socket. If the socket is unbound, {@code null} is returned.

return
the local socket address.
since
Android 1.0

        if (!isBound()) {
            return null;
        }
        return new InetSocketAddress(getLocalAddress(), getLocalPort());
    
public intgetPort()
Gets the remote port which this socket is connected to.

return
the remote port of this socket. The return value {@code -1} indicates that this socket is not connected.
since
Android 1.0

        return port;
    
public synchronized intgetReceiveBufferSize()
Gets the socket receive buffer size. ( {@code SocketOptions.SO_RCVBUF} )

return
the input buffer size.
exception
SocketException if an error occurs while getting the option value.
since
Android 1.0

        checkClosedAndBind(false);
        return ((Integer) impl.getOption(SocketOptions.SO_RCVBUF)).intValue();
    
public java.net.SocketAddressgetRemoteSocketAddress()
Gets the address and port of the connected remote host. If this socket is not connected yet, {@code null} is returned.

return
the remote socket address.
since
Android 1.0

        if (!isConnected()) {
            return null;
        }
        return new InetSocketAddress(getInetAddress(), getPort());
    
public booleangetReuseAddress()
Gets the state of the socket option {@code SocketOptions.SO_REUSEADDR}.

return
{@code true} if the option is enabled, {@code false} otherwise.
throws
SocketException if the socket is closed or the option is invalid.
since
Android 1.0

        checkClosedAndBind(false);
        return ((Boolean) impl.getOption(SocketOptions.SO_REUSEADDR))
                .booleanValue();
    
public synchronized intgetSendBufferSize()
Gets the socket send buffer size. ( {@code SocketOptions.SO_SNDBUF} )

return
the output buffer size.
exception
SocketException if an error occurs while getting the option value.
since
Android 1.0

        checkClosedAndBind(false);
        return ((Integer) impl.getOption(SocketOptions.SO_SNDBUF)).intValue();
    
public synchronized intgetSoTimeout()
Gets the socket receive timeout in milliseconds. The return value {@code 0} implies the timeout is disabled/infinitive. ( {@code SocketOptions.SO_TIMEOUT} )

return
the socket receive timeout.
exception
SocketException if an error occurs while getting the option value.
since
Android 1.0

        checkClosedAndBind(false);
        return ((Integer) impl.getOption(SocketOptions.SO_TIMEOUT)).intValue();
    
public intgetTrafficClass()
Gets the value of the type-of-service socket option {@code SocketOptions.IP_TOS}.

return
the type-of-service socket option value.
throws
SocketException if the socket is closed or the option is invalid.
since
Android 1.0

        checkClosedAndBind(false);
        return ((Number) impl.getOption(SocketOptions.IP_TOS)).intValue();
    
public booleanisBound()
Determines whether the socket is bound to an address or not.

return
{@code true} if the socket is bound, {@code false} otherwise.
since
Android 1.0

        return isBound;
    
public booleanisClosed()
Gets the state of this socket.

return
{@code true} if the socket is closed, {@code false} otherwise.
since
Android 1.0

        return isClosed;
    
public booleanisConnected()
Determines whether the socket is connected to a target host.

return
{@code true} if the socket is connected, {@code false} otherwise.
since
Android 1.0

        return isConnected;
    
booleanisMulticastSocket()
Indicates whether this socket is multicast or not.

return
the return value is always {@code false}.
since
Android 1.0

        return false;
    
public synchronized voidreceive(java.net.DatagramPacket pack)
Receives a packet from this socket and stores it in the argument {@code pack}. All fields of {@code pack} must be set according to the data received. If the received data is longer than the packet buffer size it is truncated. This method blocks until a packet is received or a timeout has expired. If a security manager exists, its {@code checkAccept} method determines whether or not a packet is discarded. Any packets from unacceptable origins are silently discarded.

param
pack the {@code DatagramPacket} to store the received data.
exception
IOException if an error occurs while receiving the packet.
since
Android 1.0

        checkClosedAndBind(true);

        boolean secure = true;

        InetAddress senderAddr = null;

        int senderPort = 0;
        DatagramPacket tempPack = new DatagramPacket(new byte[1], 1);
        boolean copy = false;

        SecurityManager security = System.getSecurityManager();
        if (address != null || security != null) { // The socket is connected
            // Check pack before peeking
            if (pack == null) {
                throw new NullPointerException();
            }
            secure = false;
            while (!secure) {
                copy = false;
                try {
                    senderPort = impl.peekData(tempPack);
                    senderAddr = tempPack.getAddress();
                } catch (SocketException e) {
                    if (e.getMessage().equals(
                            "The socket does not support the operation")) { //$NON-NLS-1$
                        tempPack = new DatagramPacket(new byte[pack.length],
                                pack.getLength());
                        impl.receive(tempPack);
                        senderAddr = tempPack.getAddress();
                        senderPort = tempPack.getPort();
                        copy = true;
                    } else {
                        throw e;
                    }
                }
                if (address == null) {
                    try {
                        security.checkAccept(senderAddr.getHostName(),
                                senderPort);
                        if (!copy) {
                            secure = true;
                        }
                        break;
                    } catch (SecurityException e) {
                        if (!copy) {
                            if (tempPack == null) {
                                tempPack = new DatagramPacket(
                                        new byte[pack.length], pack.length);
                            }
                            impl.receive(tempPack);
                        }
                    }
                } else if (port == senderPort && address.equals(senderAddr)) {
                    if (!copy) {
                        secure = true;
                    }
                    break;
                } else if (!copy) {
                    if (tempPack == null) {
                        tempPack = new DatagramPacket(new byte[pack.length],
                                pack.length);
                    }
                    impl.receive(tempPack);
                }
            }
        }
        if (copy) {
            System.arraycopy(tempPack.getData(), 0, pack.getData(), pack
                    .getOffset(), tempPack.getLength());
            pack.setLength(tempPack.getLength());
            pack.setAddress(tempPack.getAddress());
            pack.setPort(tempPack.getPort());
        }
        if (secure) {
            impl.receive(pack);
        }
    
public voidsend(java.net.DatagramPacket pack)
Sends a packet over this socket. The packet must satisfy the security policy before it may be sent. If a security manager is installed, this method checks whether it is allowed to send this packet to the specified address.

param
pack the {@code DatagramPacket} which has to be sent.
exception
IOException if an error occurs while sending the packet.
since
Android 1.0

        checkClosedAndBind(true);

        InetAddress packAddr = pack.getAddress();
        if (address != null) { // The socket is connected
            if (packAddr != null) {
                if (!address.equals(packAddr) || port != pack.getPort()) {
                    throw new IllegalArgumentException(Msg.getString("K0034")); //$NON-NLS-1$
                }
            } else {
                pack.setAddress(address);
                pack.setPort(port);
            }
        } else {
            // not connected so the target address is not allowed to be null
            if (packAddr == null) {
                if (pack.port == -1) {
                    // KA019 Destination address is null
                    throw new NullPointerException(Msg.getString("KA019")); //$NON-NLS-1$
                }
                return;
            }
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                if (packAddr.isMulticastAddress()) {
                    security.checkMulticast(packAddr);
                } else {
                    security.checkConnect(packAddr.getHostName(), pack
                            .getPort());
                }
            }
        }
        impl.send(pack);
    
public voidsetBroadcast(boolean broadcast)
Sets the socket option {@code SocketOptions.SO_BROADCAST}. This option must be enabled to send broadcast messages.

param
broadcast the socket option value to enable or disable this option.
throws
SocketException if the socket is closed or the option could not be set.
since
Android 1.0

        checkClosedAndBind(false);
        impl.setOption(SocketOptions.SO_BROADCAST, broadcast ? Boolean.TRUE
                : Boolean.FALSE);
    
public static synchronized voidsetDatagramSocketImplFactory(java.net.DatagramSocketImplFactory fac)
Sets the socket implementation factory. This may only be invoked once over the lifetime of the application. This factory is used to create a new datagram socket implementation. If a security manager is set its method {@code checkSetFactory()} is called to check if the operation is allowed. A {@code SecurityException} is thrown if the operation is not allowed.

param
fac the socket factory to use.
exception
IOException if the factory has already been set.
see
DatagramSocketImplFactory
since
Android 1.0

        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkSetFactory();
        }
        if (factory != null) {
            throw new SocketException(Msg.getString("K0044")); //$NON-NLS-1$
        }
        factory = fac;
    
public synchronized voidsetReceiveBufferSize(int size)
Sets the socket receive buffer size. This buffer size determines which the maximum packet size is that can be received over this socket. It depends on the network implementation what will happen if the packet is bigger than the buffer size. ( {@code SocketOptions.SO_RCVBUF} )

param
size the buffer size in bytes. The size must be at least one byte.
exception
SocketException if an error occurs while setting the option.
since
Android 1.0

        if (size < 1) {
            throw new IllegalArgumentException(Msg.getString("K0035")); //$NON-NLS-1$
        }
        checkClosedAndBind(false);
        impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
    
public voidsetReuseAddress(boolean reuse)
Sets the socket option {@code SocketOptions.SO_REUSEADDR}. This option has to be enabled if more than one UDP socket wants to be bound to the same address. That could be needed for receiving multicast packets.

There is an undefined behavior if this option is set after the socket is already bound.

param
reuse the socket option value to enable or disable this option.
throws
SocketException if the socket is closed or the option could not be set.
since
Android 1.0

        checkClosedAndBind(false);
        impl.setOption(SocketOptions.SO_REUSEADDR, reuse ? Boolean.TRUE
                : Boolean.FALSE);
    
public synchronized voidsetSendBufferSize(int size)
Sets the socket send buffer size. This buffer size determines which the maximum packet size is that can be sent over this socket. It depends on the network implementation what will happen if the packet is bigger than the buffer size. ( {@code SocketOptions.SO_SNDBUF} )

param
size the buffer size in bytes. The size must be at least one byte.
exception
SocketException if an error occurs while setting the option.
since
Android 1.0

        if (size < 1) {
            throw new IllegalArgumentException(Msg.getString("K0035")); //$NON-NLS-1$
        }
        checkClosedAndBind(false);
        impl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(size));
    
public synchronized voidsetSoTimeout(int timeout)
Sets the timeout period in milliseconds for the {@code receive()} method. This receive timeout defines the period the socket will block waiting to receive data before throwing an {@code InterruptedIOException}. The value {@code 0} (default) is used to set an infinite timeout. To have effect this option must be set before the blocking method was called. ( {@code SocketOptions.SO_TIMEOUT} )

param
timeout the timeout period in milliseconds or {@code 0} for infinite.
exception
SocketException if an error occurs while setting the option.
since
Android 1.0

        if (timeout < 0) {
            throw new IllegalArgumentException(Msg.getString("K0036")); //$NON-NLS-1$
        }
        checkClosedAndBind(false);
        impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(timeout));
    
public voidsetTrafficClass(int value)
Sets the socket option {@code SocketOptions.IP_TOS}. This option defines the value of the type-of-service field of the IP-header for every packet sent by this socket. The value could be ignored by the underlying network implementation.

Values between {@code 0} and {@code 255} inclusive are valid for this option.

param
value the socket option value to be set as type-of-service.
throws
SocketException if the socket is closed or the option could not be set.
since
Android 1.0

        checkClosedAndBind(false);
        if (value < 0 || value > 255) {
            throw new IllegalArgumentException();
        }
        impl.setOption(SocketOptions.IP_TOS, Integer.valueOf(value));