|
|||||||||
| 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 PacketEvents 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
PacketEvents 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 clones 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 cloned 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 PacketEventQueues 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 PacketEventQueues. |
void |
interruptPacketEventQueues()
Interrupt any threads waiting for PacketEvents on their PacketEventQueues. |
boolean |
isEmpty()
Checks if there are any open PacketEventQueues. |
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()
PacketEvents on their PacketEventQueues.public boolean isEmpty()
PacketEventQueues.public int getSize()
PacketEventQueues.
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||