public class AsyncDatagramSocket extends AbstractAsyncDatagramSocket
AsyncDatagramSocket
encapsulates a
DatagramChannel
instance, passing I/O events back to DatagramListener
.
UDP is a simpler protocol than TCP because there is no
guarantee that a packet will be delivered to its destination
or that packets will arrive in the same order as sent. So you
would expect
AsyncDatagramSocket
to have a simpler interface than AsyncSocket
- and you
would be correct.
Opening a UDP connection follows these steps:
datagram socket listener interface
.
An instance of this class handles the async datagram
socket callbacks.
Since UDP is connection-less (more on that
later) and datagram packets are
immediately transmitted, the listener has no
handleOpen
,
handleClose
, and handleOutputAvailable
callback methods. This reduces
DatagramListener
to
two callbacks:
handleInput(ByteBuffer, InetSocketAddress, AbstractAsyncDatagramSocket)
:
passes the latest datagram packet to the listener stored
in the ByteBuffer
.
handleError(Throwable, AbstractAsyncDatagramSocket)
:
reports a recoverable error occurring on the datagram
socket.
Async UDP sockets are built in the same way as
an async TCP socket
. Again, the
datagram listener instance is stored in a variable named
dgramListener
:
final AsyncDatagramSocket.DatagramBuilder builder = AsyncDatagramSocket.builder();
final AsyncSocket socket = builder.inputBufferSize(512) // Optional. Defaults to ENetConfigure.DEFAULT_BUFFER_SIZE.
.outputBufferSize(512) // Optional. Defaults to ENetConfigure.DEFAULT_BUFFER_SIZE.
.byteOrder(ByteOrder.BIG_ENDIAN) // Optional. Defaults to ByteOrder.LITTLE_ENDIAN
.listener(dgramListener) // Required.
.selector("dgramSelector") // Optional. Defaults to AsyncChannel.defaultSelector().
.build();
UDP sockets do not "connect" in the manner of a TCP socket. An open UDP socket may send a packet to any other open UDP socket. There are five methods to open an async UDP socket:
AsyncDatagramSocket.open()
:
opens an IPv4 UDP socket with the local port bound to any
available ephemeral port.
AsyncDatagramSocket.open(ProtocolFamily)
:
opens either an IPv4 or IPv6 UDP socket with the local
port bound to any available ephemeral port.
AsyncDatagramSocket.open(SocketAddress)
:
opens an IPv4 UDP socket with the local port bound to the
given address.
AsyncDatagramSocket.open(SocketAddress, ProtocolFamily)
:
opens either an IPv$ or IPv6 UDP socket wit the local port
bound to any available ephemeral port.
AsyncDatagramSocket.open(DatagramChannel)
:
wraps the AsyncDatagramSocket
around an open
datagram channel.
An open UDP socket may be "connected" to another datagram
using the methods
AsyncDatagramSocket.connect(SocketAddress)
.
Once connected all packets are sent to that address. This
connection is dropped using the method
AsyncDatagramSocket.disconnect()
.
UDP sends bytes in individual packets rather than a continuous
stream. The send
method used depends on whether the
UDP socket is "connected" or not. If not connected, then the
two methods are:
AsyncDatagramSocket(byte[], SocketAddress)
:
sends the entire byte[]
to the given address.
AsyncDatagramSocket(byte[], int, int, SocketAddress)
:
sends the specified number of byte[]
starting at
offset to the given address.
The connected UDP socket sends are similar:
AsyncDatagramSocket(byte[])
:
sends the entire byte[]
to the given address.
AsyncDatagramSocket(byte[], int, int)
:
sends the specified number of byte[]
starting at
offset to the given address.
A targeted send (one providing an address) may be used with a connect UDP socket. It means that the target address overrides the connect address.
UDP send
methods do not throw
BufferOverflowException
because there is no way to
recover from an overflow. The bytes passed to send
are
sent in a single datagram. Those bytes are first placed into
the associated buffer and buffer used to transmit the packet.
If the send bytes exceed the buffer size then the send has no
way to succeed; there is no way to recover from the fact that
the bytes cannot fit into a single packet.
Async datagram sockets also support the buffer writer paradigm
DatagramBufferWriter
.
The
fill
method works just like BufferWriter.fill
except it
returns the target SocketAddress
to which the packet
should be sent. If the datagram socket is connected then
DatagramBufferWriter.fill
may return null
.
Again, if DatagramBufferWriter.fill
overflows the
ByteBuffer
then the buffer contents are discarded
and the send fails.
DatagramListener
,
AsyncSocket
,
AsyncMulticastSocket
Modifier and Type | Class and Description |
---|---|
static class |
AsyncDatagramSocket.DatagramBuilder
Constructs an
AsyncDatagramSocket instance based
on the parameters set via this builder's API. |
AbstractAsyncDatagramSocket.AbstractDatagramBuilder<B extends AbstractAsyncDatagramSocket.AbstractDatagramBuilder<?>>
AsyncChannel.BufferMode, AsyncChannel.ChannelBuilder<B extends AsyncChannel.ChannelBuilder<?>>, AsyncChannel.ConnectState
mBoundFlag, mListener, mOpenFlag, sLogger
LOCALHOST, mChannel, mInputBuffer, mLocalAddress, mOutputBuffer, mOutputLock, mRemoteAddress, mSelectorThread
Modifier | Constructor and Description |
---|---|
protected |
AsyncDatagramSocket(AbstractAsyncDatagramSocket.AbstractDatagramBuilder<?> builder)
Protected constructor used to create a
AsyncSecureDatagramSocket instance. |
Modifier and Type | Method and Description |
---|---|
static AsyncDatagramSocket.DatagramBuilder |
builder()
Returns the builder used to open new
AsyncDatagramSocket instances. |
void |
connect(java.net.SocketAddress remoteAddr)
"Connects" the datagram socket to the given remote socket
address.
|
void |
disconnect()
Removes an in-place datagram "connection".
|
protected void |
doOpen(java.nio.channels.DatagramChannel channel)
Performs actual work of encapsulating an "accepted"
datagram channel.
|
protected void |
doOpen(java.net.SocketAddress bindAddr,
java.net.ProtocolFamily family)
Performs the actual work of opening a datagram channel.
|
protected void |
doSend(DatagramBufferWriter writer)
Uses
writer to directly write data to outbound
buffer. |
boolean |
isConnected()
Returns
true if the datagram socket is connected
and false otherwise. |
void |
open()
Opens an unconnected IPv4 datagram socket.
|
void |
open(java.nio.channels.DatagramChannel channel)
Wraps this
AsyncDatagramSocket around an open
datagram channel. |
void |
open(java.net.ProtocolFamily family)
Opens an unconnected datagram socket for the specified
protocol.
|
void |
open(java.net.SocketAddress bindAddr)
Opens an unconnected, IPv4 datagram socket bound to the
provided port and IP address.
|
void |
open(java.net.SocketAddress bindAddr,
java.net.ProtocolFamily family)
Opens an unconnected, datagram socket for the specified
protocol and bound to the provided port and IP address.
|
void |
send(byte[] b)
Sends the given bytes as a single UDP packet directly to
the socket's peer.
|
void |
send(byte[] b,
int off,
int len)
Sends the given bytes as a single UDP packet directly to
the socket's peer.
|
void |
send(byte[] b,
int off,
int len,
java.net.SocketAddress target)
Sends the given bytes as a single UDP packet directly to
the target address.
|
void |
send(byte[] b,
java.net.SocketAddress target)
Sends the given bytes as a single UDP packet directly to
the target address.
|
void |
send(DatagramBufferWriter writer)
When it is time to send the UDP packet generated by
writer , BufferWriter.fill(ByteBuffer) is
called, passing in the outbound buffer. |
void |
send(int b)
Sends the given byte in a UDP datagram directly to the
socket's peer.
|
void |
send(int b,
java.net.SocketAddress target)
Sends the given byte in a UDP datagram directly to the
target address.
|
close, closeNow, datagramSocket, doClose, doRead, doSend, isBound, isOpen, opened, write
createSelector, defaultSelectorName, getOption, inputBufferSize, isSelector, localSocketAddress, outputBufferSize, remoteSocketAddress, selectorNames, setOption, supportedOptions
protected AsyncDatagramSocket(AbstractAsyncDatagramSocket.AbstractDatagramBuilder<?> builder)
AsyncSecureDatagramSocket
instance.builder
- contains secure datagram socket
configuration.public void send(int b, java.net.SocketAddress target) throws java.io.IOException
send
in class AbstractAsyncDatagramSocket
b
- sends this single byte to the socket's peer.target
- send the UDP packet to this address.java.lang.NullPointerException
- if target
is null
.java.nio.channels.ClosedChannelException
- if this datagram socket is closed.java.io.IOException
- if this socket is connected.public void send(byte[] b, java.net.SocketAddress target) throws java.io.IOException
send
in class AbstractAsyncDatagramSocket
b
- fill the UDP packet with this entire byte array.target
- send the UDP packet to this address.java.lang.IllegalArgumentException
- if either b
or target
is null
.java.lang.IndexOutOfBoundsException
- if b.length
exceeds the outbound buffer size
(which is set to the maximum allowed datagram size).java.nio.channels.ClosedChannelException
- if this datagram socket is closed.java.io.IOException
- if this socket is connected.public void send(byte[] b, int off, int len, java.net.SocketAddress target) throws java.io.IOException
send
in class AbstractAsyncDatagramSocket
b
- send len
bytes from this array starting
at off
offset.off
- offset into b
.len
- send this many bytes from b
.target
- send the UDP packet to this address.java.lang.IllegalArgumentException
- if either b
or target
is null
.java.lang.IndexOutOfBoundsException
- if off
or off+len
exceeds b
bounds
or len
exceeds the maximum allowed datagram size.java.nio.channels.ClosedChannelException
- if this datagram socket is closed.java.io.IOException
- if this socket is connected.public final void send(DatagramBufferWriter writer) throws java.io.IOException
writer
, BufferWriter.fill(ByteBuffer)
is
called, passing in the outbound buffer. Upon completion,
the UDP packet is sent to the target address.
This method continues to call fill(ByteBuffer)
until it throws EmptyStackException
which informs
this method that there are no more datagrams to send. This
is necessary since each fill
may be sent to a
different destination.
If this datagram socket is not connected to a
peer datagram socket, then
DatagramBufferWriter.fill(ByteBuffer)
must return a non- destination address for
the packet. If this datagram socket is connected to a
peer, then the Writer.fill(ByteBuffer)
must return
a null
destination address.
send
in class AbstractAsyncDatagramSocket
writer
- fills the outbound buffer with the UDP
packet contents and provides the target socket address.java.lang.IllegalArgumentException
- if writer
or target
is null
.java.nio.channels.ClosedChannelException
- if this datagram socket is closed.java.nio.channels.NotYetConnectedException
- if this datagram socket is not connected to a peer and
DatagramBufferWriter.fill(ByteBuffer)
returns
null
.java.io.IOException
- if an I/O error trying to post this send request.public final boolean isConnected()
true
if the datagram socket is connected
and false
otherwise.true
if the datagram socket is connected
and false
otherwise.AbstractAsyncDatagramSocket.close()
,
AbstractAsyncDatagramSocket.closeNow()
public final void open() throws java.io.IOException
IOException
.
If you need to "connect" this UDP socket to a remote
address, then call
connect(SocketAddress)
after successfully opening
this datagram socket.
If the datagram socket is used for IP multicasting, then
use open(ProtocolFamily)
to be certain that this
socket's protocol matches the multicast group address
type. If the protocol types do not match, then this
datagram socket will not be able to join the multicast
group.
java.io.IOException
- if there is a datagram socket already open or an I/O
exception occurs while opening the socket.open(ProtocolFamily)
,
open(SocketAddress)
,
open(SocketAddress, ProtocolFamily)
,
connect(SocketAddress)
,
disconnect()
,
AbstractAsyncDatagramSocket.close()
,
AbstractAsyncDatagramSocket.closeNow()
public final void open(java.net.ProtocolFamily family) throws java.io.IOException
this
datagram socket is already open,
then throws IOException
.
If you need to "connect" this UDP socket to a remote
address, then call
connect(SocketAddress)
after successfully opening
this datagram socket.
If the datagram socket will be used for IP multicasting,
then family
should correspond to the multicast
group address to which this datagram socket will join.
If the multicast group is IPv4, then set family
to
StandardProtocolFamily.INET
. If the multicast
group is IPv6, then set family
to
StandardProtocolFamily.INET6
.
family
- protocol family.java.lang.UnsupportedOperationException
- if the platform does not support the specified
family
.java.io.IOException
- if there is a datagram socket already open or an I/O
exception occurs while opening the socket.open()
,
open(SocketAddress)
,
open(SocketAddress, ProtocolFamily)
,
connect(SocketAddress)
,
disconnect()
,
AbstractAsyncDatagramSocket.close()
,
AbstractAsyncDatagramSocket.closeNow()
public final void open(java.net.SocketAddress bindAddr) throws java.io.IOException
localAddr
is
0.0.0.0, the socket is bound to the local host machine's
wildcard address. If localAddr
is null
,
then the socket is bound to any available port on the
host.
If a datagram socket is already open, then throws an
IOException
.
bindAddr
- bind the datagram socket to this address.
If null
, opens an unbound socket.java.io.IOException
- if there is a datagram socket already open or an I/O
exception occurs while opening the socket.open()
,
connect(SocketAddress)
,
disconnect()
,
AbstractAsyncDatagramSocket.close()
,
AbstractAsyncDatagramSocket.closeNow()
public final void open(java.net.SocketAddress bindAddr, java.net.ProtocolFamily family) throws java.io.IOException
localAddr
is 0.0.0.0, the socket is bound to the
local host machine's wildcard address. If
localAddr
is null
, then the socket is
bound to any available port on the host.
If a datagram socket is already open, then throws an
IOException
.
bindAddr
- bind the datagram socket to this address.
If null
, opens an unbound socket.family
- protocol family.java.lang.UnsupportedOperationException
- if the platform does not support the specified
family
.java.io.IOException
- if there is a datagram socket already open or an I/O
exception occurs while opening the socket.open()
,
open(ProtocolFamily)
,
open(SocketAddress)
,
connect(SocketAddress)
,
disconnect()
,
AbstractAsyncDatagramSocket.close()
,
AbstractAsyncDatagramSocket.closeNow()
public final void open(java.nio.channels.DatagramChannel channel) throws java.io.IOException
AsyncDatagramSocket
around an open
datagram channel. channel
is expected to be
open and configured by the caller.channel
- wrap this channel.java.io.IOException
- if channel
is closed.public void connect(java.net.SocketAddress remoteAddr) throws java.io.IOException
remoteAddr
only. Once successfully connected,
datagrams cannot be received or sent to any other address.
This datagram socket remains connected until either
disconnected
or
closed
.
This method performs exactly the same security checks as
the
connect
method of the DatagramSocket
class. If a
security manager has been installed then this method
verifies that its
checkAccept
and
checkConnect
methods permit datagrams to be received from and sent to
the remoteAddr
.
This method may be invoked at any time. It will not have any effect on read or write operations already in progress when invoked.
remoteAddr
- connect to this remote address.java.lang.NullPointerException
- if remoteAddr
is null
.java.lang.IllegalStateException
- if datagram socket is already connected or closed.java.io.IOException
- if some I/O error occurs.disconnect()
,
AbstractAsyncDatagramSocket.close()
,
AbstractAsyncDatagramSocket.closeNow()
public void disconnect() throws java.io.IOException
This method may be invoked at any time. It will not have any effect on read or write operations already in progress when invoked.
If this datagram socket is not connected or is closed, then invoking this method has no effect.
java.io.IOException
- if some I/O error occurs.connect(java.net.SocketAddress)
,
AbstractAsyncDatagramSocket.close()
,
AbstractAsyncDatagramSocket.closeNow()
public final void send(int b) throws java.io.IOException
b
- sends this single byte to the socket's peer.java.nio.channels.ClosedChannelException
- if this datagram socket is closed.java.nio.channels.NotYetConnectedException
- if this datagram socket is not connected to a peer.java.io.IOException
- if the buffer was only partially transmitted or an
underlying I/O error occurs.public final void send(byte[] b) throws java.io.IOException
b
- fill the UDP packet with this data.java.lang.IllegalArgumentException
- if b
is null
.java.lang.IndexOutOfBoundsException
- if b.length
exceeds the outbound buffer size
(which is set to the maximum allowed datagram size).java.nio.channels.ClosedChannelException
- if this datagram socket is closed.java.nio.channels.NotYetConnectedException
- if this datagram socket is not connected to a peer.java.io.IOException
- if the buffer was only partially transmitted or an
underlying I/O error occurs.public final void send(byte[] b, int off, int len) throws java.io.IOException
b
- send len
bytes from this array starting
at off
offset.off
- offset into b
.len
- send this many bytes from b
.java.lang.IllegalArgumentException
- if b
is null
.java.lang.IndexOutOfBoundsException
- if off
or off+len
exceeds b
bounds
or len
exceeds the maximum allowed datagram size.java.nio.channels.ClosedChannelException
- if this datagram socket is closed.java.nio.channels.NotYetConnectedException
- if this datagram socket is not connected to a peer.java.io.IOException
- if the buffer was only partially transmitted or an
underlying I/O error occurs.public static AsyncDatagramSocket.DatagramBuilder builder()
AsyncDatagramSocket
instances.AsyncDatagramSocket
builder.protected void doOpen(java.net.SocketAddress bindAddr, java.net.ProtocolFamily family) throws java.io.IOException
bindAddr
- bind the local address to this port.family
- communication protocol family.java.io.IOException
- if attempt to open datagram channel fails.protected void doOpen(java.nio.channels.DatagramChannel channel) throws java.io.IOException
channel
- "accepted" datagram channel.java.io.IOException
- if attempt to register datagram channel with selector
fails.protected void doSend(DatagramBufferWriter writer) throws java.io.IOException
writer
to directly write data to outbound
buffer. This by-passes the need to write data to a
byte array first and then place that array into the
outbound buffer.writer
- writes the next available packet to the
outbound byte buffer.java.io.IOException
- if the encoded packet failed to be sent.Copyright © 2001 - 2024. Charles W. Rapp. All rights reserved.