Skip to end of metadata
Go to start of metadata

An AsyncDatagram represents a asynchronous socket for sending and receiving datagram packets. A datagram socket is the sending or receiving point for a packet delivery service. Each packet sent or received on a datagram socket is individually addressed and routed. Multiple packets sent from one machine to another may be routed differently, and may arrive in any order.

Users of AsyncDatagram are expected to be familiar with java.net.DatagramSocket and java.nio.channels.DatagramChannel as many of the method of are taken directly from this class. We will not cover any of these similar methods but merely refer to the Javadoc of AsyncDatagram and DatagramSocket. AsyncDatagram supports all operations available on both DatagramSocket and DatagramChannel. However, manipulation of socket options must be performed on the DatagramSocket object available by calling socket().

NOTICE: There is currently no ability to use multicast datagram sockets.

Opening an AsyncDatagram

There are four standard ways to open an AsyncDatagram each explained in the 5 minute introduction

Standard mode

Offerable mode

Queue mode

Callback mode

Connecting and Disconnecting

By default AsyncDatagram sockets are not connected. In order to avoid the overhead of security checks on every send and receive operation you can choose to connect a datagram:

This will connect the datagram to a remote address; in this case codehaus.org on port 13. When a socket is connected to a remote address, packets may only be sent to or received from that address.

This method is non-blocking and if the remote destination to which the socket is connected to does not exist, or is otherwise unreachable, and if an ICMP destination unreachable packet has been received for that address, then a subsequent call to send or receive may throw a PortUnreachableException. Note, there is no guarantee that the exception will be thrown.

A caller's permission to send and receive datagrams to a given host and port are checked at connect time. When a socket is connected, receive and send will not perform any security checks on incoming and outgoing packets, other than matching the packet's and socket's address and port.

To disconnect a datagram you just call the disconnect method which does nothing if the datagram is not connected.

Sending Data

To send data to a remote address you can use the send method.

If you have choosen to connect your datagram to a remote host, there are three additional methods that can be used, these methods will use the address that wassupplied when the datagram was connected.

The following snippet will connect to a remote host and send a HelloWorld-String.

Receiving Data (Hollywood principle)

Because the datagram is operating in asynchronous mode, the reception of data is different from how data is normally received on datagrams with synchronous semantics.
If the socket is allowed to block we can call the read operation on a socket which block waiting for data to arrive. If we are not allowed to block the object must instead call a designated callback object, an instance of ReadHandler every time there is data to process. This ReadHandler can be installed by calling the asynchronous datagrams setReader() method.

Whenever data appears in the network buffer the handle() method of the ReadHandler is called passing along the AsyncDatagram.The AsyncDatagrams's getSource() method can then be called, returning an AsyncDatagramSource where data can be read from.

As seen in the following example.

If the handle() method throws any kind of exception the asynchronous datagram will close immediatly.

Backpressure

To protect your application against such things as slow modem links, its possible to specify certain restrictions on the size of the number of outstanding writes. if you are not familiar with the concept of backpressuring try taking a look at this article

By calling setBufferLimit you can specify the maximum number of bytes that are allowed in the internal buffer for the asynchronous datagram. Trying to call one of the write methods (or send method) with a buffer that would exceed the total number of bytes will throw an OverloadException

The last invocation of write will throw OverloadException, assuming the underlying I/O layer did not manage to write the payload of any of the buffer to the network device before the last call to write.

Calling setBufferLimit with a limit that is less then the number of currently waiting bytes will not effect these pending events, a call to setBufferLimit only effects later calls to the various send/write-methods.

The setWriteQueueLimit method sets a limit on the number of outstanding write events. In the above example a call to setWriteQueueLimit(2) will throw a OverloadException on the third invocation of write, again assuming the underlying I/O layer did not manage to write the payload of any of the buffer to the network device before the last call to write.

setWriteQueueLimit and setWriteQueueLimit can be used in a combination or each as a separate backpressure mechanism.

Coloring

Mutual exclusion is used for avoiding concurrent use of un-shareable resources. One of the original benefits of using event-based programs on single processor machines was that there was no need to worry about concurrency control. However multi-core and multiprocessor machines are in common use today so another solution must be found. We provide a simple solution for callbacks where we use declarations to enable mutual exclusion.

In this model each callback is given a specific color that is consistent across the lifetime of the Async.

Events with different colors are allowed to be handled in parallel. Events with the same color must be handled once at a time. A special Executor can then serialize the execution of these events in such a way that no events with the same color is executed concurrently.

Any Executor running callbacks for an AsyncDatagram will receive a Runnable that implements the Colored interface.

Closing

To close an AsyncDatagram you simple call its close() method

Note: Currently we do not support any kind of linger mechanism, so make sure all data has been sent before closing the datagram.

Other methods

There are a number of other methods present, and not described previously, in AsyncDatagram that is not available in the ordinary DatagramSocket class.

Method

Description

AsyncDatagram getGroup()

Returns the group that this datagram belongs to

long getId()

Returns an unique (long) id for the datagram

DatagramSocket socket()

Retrieves a datagram socket (java.net.DatagramSocket) associated with this channel. The returned object will not declare any public methods that are not declared in the DatagramSocket class. Manipulation of socket options must be performed through the returned object.

AsyncDatagram setGroup(AsyncDatagramGroup)

Sets the group that this datagram belongs to.

Methods taken from DatagramSocket

These methods are all taken from DatagramSocket(Javadoc) and has similar semantics.

Method

Description

AsyncDatagram bind(SocketAddress)

Binds this datagram socket to a specific address & port.

AsyncDatagram connect(SocketAddress)

Connects the socket to a remote address for this socket.

AsyncDatagram disconnect()

Disconnects the socket.

InetAddress getInetAddress()

Returns the address to which this socket is connected. Returns null if the socket is not connected.

InetAddress getLocalAddress()

Gets the local address to which the socket is bound.

int getLocalPort()

Returns the port number on the local host to which this socket is bound.

SocketAddress getLocalSocketAddress()

Returns the address of the endpoint this socket is bound to, or null if it is not bound yet.

int getPort()

Returns the port for this socket on the remote host. Returns -1 if the socket is not connected.

SocketAddress getRemoteSocketAddress()

Returns the address of the endpoint this socket is connected to, or null if it is unconnected.

boolean isBound()

Returns the binding state of the socket.

boolean isConnected()

Returns the connection state of the socket.

Labels
  • None