|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--jcifs.util.MultiDatagramSocket
MultiDatagramSocket
employs a simple linked list queuing mechanism and an
internal thread dedicated to reading from the socket to allow multiple
threads to concurrently send and receive datagram packets on the same
port at rates independent from one another. There are three classes
that encapsulate this functionality: MultiDatagramSocket
,
PacketEventQueue
, and PacketEvent
.
MultiDatagramSocket is, at first glance, almost identical to
DatagramSocket
but instead of calling receive
you obtain a PacketEventQueue
by calling createPacketEventQueue()
and read in PacketEvent
s at liesure by calling PacketEventQueue.getNextPacketEvent()
on the PacketEventQueue
. PacketEvent
encapsulates the DatagramPacket
, the reception time,
and is Cloneable
. The PacketEventQueue.getNextPacketEvent()
method will block until a packet is received if there are no
PacketEvent
s in the queue.
This is useful when different tasks are servicing request on the same port. You don't have to worry about tasks stealing each other's packets. The netbios name service of jcifs uses it to send and receive requests synchronously. Without this, a failing request(which can take up to 15 seconds) would prevent another request from being serviced until it finished. This may all seem overkill but it is surprisingly easy to implement. All three classes total a meager 250 lines of code. See MultiDatagramSocket.txt for more information.
Important Note: When the internal thread enqueues an incoming
packet it clone
s it only once so that when another packet comes in the
data is not overwritten in the queues. But the data(DatagramPacket
, it's
buffer, and so on) are not clone
d for entry into each queue. In other
words, with each incoming packet, the same PacketEvent
object is queued
to all PacketEventQueues. So you CANNOT MODIFY the data of a PacketEvent
without cloning it first or other PacketEventQueue
s will observe the
changes. This is one reason why PacketEvent
is Cloneable
. This was done
for purposes of efficiency. I have found that in practice packets are
simply examined and not modified. So if you want to recycle a packet
for it's data just PacketEvent.clone()
it first.
PacketEventQueue
,
PacketEvent
,
DatagramSocket
,
DatagramPacket
,
Cloneable
Constructor Summary | |
MultiDatagramSocket()
Construct a new MultiDatagramSocket . |
|
MultiDatagramSocket(int port)
Construct a new MultiDatagramSocket on the specified port. |
|
MultiDatagramSocket(int port,
InetAddress addr)
Construct a new MultiDatagramSocket on the specified port
that binds to the specified interface. |
Method Summary | |
PacketEventQueue |
createPacketEventQueue()
Create a new PacketEventQueue . |
InetAddress |
getLocalAddress()
Retrieves the local hosts interface this socket is running bound to. |
int |
getLocalPort()
Returns the local port this socket is set to run on. |
int |
getSize()
The number of open PacketEventQueue s. |
void |
interruptPacketEventQueues()
Interrupt any threads waiting for PacketEvent s on their PacketEventQueue s. |
boolean |
isEmpty()
Checks if there are any open PacketEventQueue s. |
void |
removePacketEventQueue(PacketEventQueue peq)
Discard the PacketEventQueue (ie stop listening). |
void |
run()
|
void |
send(DatagramPacket p)
Send a datagram. |
void |
start()
Start this MultiDatagramSocket . |
void |
stop()
Stop the MultiDatagramSocket . |
Methods inherited from class java.lang.Object |
clone,
equals,
finalize,
getClass,
hashCode,
notify,
notifyAll,
toString,
wait,
wait,
wait |
Constructor Detail |
public MultiDatagramSocket()
MultiDatagramSocket
.public MultiDatagramSocket(int port)
MultiDatagramSocket
on the specified port.public MultiDatagramSocket(int port, InetAddress addr)
MultiDatagramSocket
on the specified port
that binds to the specified interface.Method Detail |
public void run()
public void start() throws SocketException
MultiDatagramSocket
. After 30 seconds of no activity the socket
will timeout and close. Should another packet arrive the socket will
restart and service the request as normal.public void stop()
MultiDatagramSocket
. You can start and stop MultiDatagramSocket
any number
of times without worrying about reinstantiating.public void send(DatagramPacket p) throws IOException
p
- the DatagramPacket
to sendpublic InetAddress getLocalAddress()
public int getLocalPort()
public PacketEventQueue createPacketEventQueue()
PacketEventQueue
. As soon as a thread creates a new PacketEventQueue
it is
currently queueing packets. So if the thread chooses not to call PacketEventQueue.getNextPacketEvent()
for a while it may get
a back log of packets. This is probably not what you want. Obtain the
PacketEventQueue
just before the calling thread is going to try
to retrive a packet.public void removePacketEventQueue(PacketEventQueue peq)
PacketEventQueue
(ie stop listening). It is always
very importantant to release a PacketEventQueue
or the
socket will maintain it's reference and queue packet events to it.
Probably get a VM memory error eventually.public void interruptPacketEventQueues()
PacketEvent
s on their PacketEventQueue
s.public boolean isEmpty()
PacketEventQueue
s.public int getSize()
PacketEventQueue
s.
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |