public class MergingDatagramSocket extends DatagramSocket
DatagramSocket
implementation which merges a set of sockets.
It maintains a thread reading from each of the underlying sockets. Thus
received datagrams are provided via the receive(DatagramPacket)
API, in the order in which they were originally received (or close to it,
since the implementation is only based on timestamps).
One of the underlying sockets is used as a delegate, and handles sending
via send(DatagramPacket)
and calls to
getLocalPort()
, getLocalAddress()
and
getLocalSocketAddress()
.Modifier and Type | Class and Description |
---|---|
private class |
MergingDatagramSocket.SocketContainer
Contains one of the sockets which this
MergingDatagramSocket
merges, and objects associated with the socket, including a thread
which loops reading from it. |
Modifier and Type | Field and Description |
---|---|
protected MergingDatagramSocket.SocketContainer |
active
The
MergingDatagramSocket.SocketContainer considered active, i.e. |
private static Logger |
classLogger
The
Logger used by the MergingDatagramSocket class and
its instances for logging output. |
private boolean |
closed
The flag which indicates whether this socket is closed.
|
private Logger |
logger
The
Logger used by MergingDatagramSocket instances. |
private int |
numDiscardedPackets
The number of packets which were read from an underlying socket, but were
discarded because they were not accepted by
accept(DatagramPacket) . |
private Object |
receiveLock
Calls to
receive(java.net.DatagramPacket) will wait on this
object in case no packet is available for reading. |
private MergingDatagramSocket.SocketContainer[] |
socketContainers
Stores the underlying sockets.
|
private Object |
socketContainersSyncRoot
Used to control access to
socketContainers . |
private int |
soTimeout
If non-zero,
receive(java.net.DatagramPacket) will attempt to
return within this many milliseconds, and will throw a
SocketTimeoutException if no packet has been read. |
Constructor and Description |
---|
MergingDatagramSocket()
Initializes a new
MergingDatagramSocket instance. |
MergingDatagramSocket(Logger levelDelegate)
Initializes a new
MergingDatagramSocket instance. |
Modifier and Type | Method and Description |
---|---|
protected boolean |
accept(DatagramPacket p)
Checks whether a particular
DatagramPacket , received from one of
the underlying sockets of thins merging socket, should be accepted and
provided for reception from this MergingDatagramSocket . |
void |
add(DatagramSocket socket)
Adds a
DatagramSocket instance to this merging socket. |
void |
add(DelegatingSocket socket)
Adds a
DelegatingSocket instance to this merging socket. |
void |
add(IceSocketWrapper wrapper)
Adds the socket instance wrapped by
wrapper to this merging
socket. |
void |
close() |
private void |
doAdd(Object socket)
Adds a socket (either a
DatagramSocket or a
DelegatingSocket ) to the list of underlying sockets merged by
this MergingDatagramSocket . |
private void |
doRemove(Object socket)
Removes a socket from the list of sockets merged by this
MergingDatagramSocket . |
protected MergingDatagramSocket.SocketContainer |
getActiveSocket()
TODO
|
InetAddress |
getLocalAddress() |
int |
getLocalPort() |
SocketAddress |
getLocalSocketAddress() |
int |
getSoTimeout() |
private int |
indexOf(MergingDatagramSocket.SocketContainer[] socketContainers,
Object socket)
Returns the index in
socketContainers of the
MergingDatagramSocket.SocketContainer with socket equal to socket , or -1 if
such a MergingDatagramSocket.SocketContainer doesn't exist. |
protected void |
initializeActive(IceSocketWrapper socketWrapper,
TransportAddress remoteAddress)
Initializes the active socket of this
MergingDatagramSocket . |
boolean |
isClosed() |
void |
receive(DatagramPacket p) |
void |
remove(DatagramSocket socket)
Removes a specific
DatagramSocket from the list of sockets
merged by this MergingDatagramSocket . |
void |
remove(DelegatingSocket socket)
Removes a specific
DelegatingSocket from the list of sockets
merged by this MergingDatagramSocket . |
void |
send(DatagramPacket pkt)
The current implementation delegates to the first container, but this is
subject to change.
|
void |
setSoTimeout(int soTimeout) |
bind, connect, connect, disconnect, getBroadcast, getChannel, getInetAddress, getPort, getReceiveBufferSize, getRemoteSocketAddress, getReuseAddress, getSendBufferSize, getTrafficClass, isBound, isConnected, setBroadcast, setDatagramSocketImplFactory, setReceiveBufferSize, setReuseAddress, setSendBufferSize, setTrafficClass
private static final Logger classLogger
Logger
used by the MergingDatagramSocket
class and
its instances for logging output.private final Object socketContainersSyncRoot
socketContainers
.private MergingDatagramSocket.SocketContainer[] socketContainers
private final Object receiveLock
receive(java.net.DatagramPacket)
will wait on this
object in case no packet is available for reading.private int soTimeout
receive(java.net.DatagramPacket)
will attempt to
return within this many milliseconds, and will throw a
SocketTimeoutException
if no packet has been read.protected MergingDatagramSocket.SocketContainer active
MergingDatagramSocket.SocketContainer
considered active, i.e. the one which should
be used for sending.private boolean closed
private int numDiscardedPackets
accept(DatagramPacket)
.
Access to this field should be protected by receiveLock
.private final Logger logger
Logger
used by MergingDatagramSocket
instances.public MergingDatagramSocket() throws SocketException
MergingDatagramSocket
instance.SocketException
public MergingDatagramSocket(Logger levelDelegate) throws SocketException
MergingDatagramSocket
instance.levelDelegate
- the Logger
instance which dictates the
logging level for the new MergingDatagramSocket
instance.SocketException
public boolean isClosed()
isClosed
in class DatagramSocket
public void close()
close
in interface Closeable
close
in interface AutoCloseable
close
in class DatagramSocket
public void setSoTimeout(int soTimeout)
setSoTimeout
in class DatagramSocket
public int getSoTimeout()
getSoTimeout
in class DatagramSocket
public void send(DatagramPacket pkt) throws IOException
send
in class DatagramSocket
pkt
- the datagram to send.IOException
public void add(DelegatingSocket socket)
DelegatingSocket
instance to this merging socket. Note
that this will start a thread reading from the added socket.socket
- the socket to add.public void add(IceSocketWrapper wrapper)
wrapper
to this merging
socket. Note that this will start a thread reading from the added socket.wrapper
- the wrapper of the socket to add.public void add(DatagramSocket socket)
DatagramSocket
instance to this merging socket. Note
that this will start a thread reading from the added socket.socket
- the socket to add.private void doAdd(Object socket)
DatagramSocket
or a
DelegatingSocket
) to the list of underlying sockets merged by
this MergingDatagramSocket
.socket
- the socket to add.public void remove(DatagramSocket socket)
DatagramSocket
from the list of sockets
merged by this MergingDatagramSocket
.socket
- the DatagramSocket
to remove.public void remove(DelegatingSocket socket)
DelegatingSocket
from the list of sockets
merged by this MergingDatagramSocket
.socket
- the DelegatingSocket
to remove.private void doRemove(Object socket)
MergingDatagramSocket
.socket
- the socket to remove.private int indexOf(MergingDatagramSocket.SocketContainer[] socketContainers, Object socket)
socketContainers
of the
MergingDatagramSocket.SocketContainer
with socket equal to socket
, or -1 if
such a MergingDatagramSocket.SocketContainer
doesn't exist.socket
- the DatagramSocket
to get the index of.socketContainers
of the
MergingDatagramSocket.SocketContainer
with socket equal to socket
, or -1 if
such a MergingDatagramSocket.SocketContainer
doesn't exist.protected MergingDatagramSocket.SocketContainer getActiveSocket()
public InetAddress getLocalAddress()
null
.getLocalAddress
in class DatagramSocket
public int getLocalPort()
0
.
TODO: should we return 0 (unbound) or -1 (closed) if there are no
sockets?getLocalPort
in class DatagramSocket
public SocketAddress getLocalSocketAddress()
null
.getLocalSocketAddress
in class DatagramSocket
protected boolean accept(DatagramPacket p)
DatagramPacket
, received from one of
the underlying sockets of thins merging socket, should be accepted and
provided for reception from this MergingDatagramSocket
.p
- the packet for which to decide whether to accept it or not.true
iff p
should be accepted.public void receive(DatagramPacket p) throws SocketTimeoutException, SocketClosedException
p
a packet already received from one of the
underlying sockets. The socket is chosen on the base of the timestamp
of the reception of the first packet in its queue (so that earlier
packets are received first).receive
in class DatagramSocket
SocketTimeoutException
- if a socket timeout is set, and the
call fails to receive a packet within the timeout.SocketClosedException
- if the socket is closed whileprotected void initializeActive(IceSocketWrapper socketWrapper, TransportAddress remoteAddress)
MergingDatagramSocket
.socketWrapper
- the IceSocketWrapper
instance wrapping the
actual socket that should be used. Used to find the correct
MergingDatagramSocket.SocketContainer
remoteAddress
- the remote address which was selected by ICE and
and which should be used as the target.Copyright © 2018. All rights reserved.