Retrieving Sender Information From A Non-blocking DatagramChannel

B

Bala

I have a DatagramChannel that I have added to a Java Selector. Hence
the configureblocking is set to false since the selector expects a non
blockign socket.
I have to use the DatagramChannel's receive call and cannot use the
socket.receive which reads the data in a packet due to the nonblocking
mode.

If I would have received / sent DatagramPacket using the
dc.socket().receive call, then the packet provides you the Sender
information anyways.

The problem is that I need the host/port of the sender from this
DatagramChannel. I see there are a couple of private variables within
the DatagramChannel class cachedSenderInetAddress, cachedSenderPort)
that have this information but those are private variables and I do
not see any method in the DatagramChannel or its socket to retrieve
the sender information.

Is there a way I can do this?

Here is the code snippet for the Receiver
=========================================

class CReadDatagramChannel {

DatagramChannel dc = DatagramChannel.open().configureBlocking(false);

public CReadDatagramChannel (int port, Selector selector) {
dc.socket().setReuseAddress(true);
dc.socket().bind(new InetSocketAddress(port));
dc.register(selector, SelectionKey.OP_READ, this);
}

/* This method gets invoked from the Selector on the isReadable() */
public void processRead () {
// I cannot do dc.socket().receive(packet) since the blocking is
false.
ByteBuffer socketBuffer = ByteBuffer.allocate(1024);
dc.receive (socketBuffer);
}
}


Here is the code snippet for the Sender
=======================================

class CWriteDatagramChannel {
DatagramChannel dc = DatagramChannel.open().configureBlocking(false);

public CWriteDatagramChannel (int port, Selector selector) {
dc.socket().setReuseAddress(true);
dc.socket().bind(new InetSocketAddress(port));
dc.register(selector, SelectionKey.OP_READ, this);
}

/* This method gets invoked from the Selector on the isWritable() */
pubic void processWrite (ByteBuffer writeBuffer, String host, int
port) {
// I cannot do dc.socket().write since the blocking is false.
dc.send(writeBuffer, new InetSocketAddress (host, port));
}
}


Is there a way to know the Sender after the receive call in the
Reader?
 
R

Robert Klemme

I have a DatagramChannel that I have added to a Java Selector. Hence
the configureblocking is set to false since the selector expects a non
blockign socket.
I have to use the DatagramChannel's receive call and cannot use the
socket.receive which reads the data in a packet due to the nonblocking
mode.

If I would have received / sent DatagramPacket using the
dc.socket().receive call, then the packet provides you the Sender
information anyways.

The problem is that I need the host/port of the sender from this
DatagramChannel. I see there are a couple of private variables within
the DatagramChannel class cachedSenderInetAddress, cachedSenderPort)
that have this information but those are private variables and I do
not see any method in the DatagramChannel or its socket to retrieve
the sender information.

Is there a way I can do this?

Here is the code snippet for the Receiver
=========================================

class CReadDatagramChannel {

DatagramChannel dc = DatagramChannel.open().configureBlocking(false);

public CReadDatagramChannel (int port, Selector selector) {
dc.socket().setReuseAddress(true);
dc.socket().bind(new InetSocketAddress(port));
dc.register(selector, SelectionKey.OP_READ, this);
}

/* This method gets invoked from the Selector on the isReadable() */
public void processRead () {
// I cannot do dc.socket().receive(packet) since the blocking is
false.
ByteBuffer socketBuffer = ByteBuffer.allocate(1024);
dc.receive (socketBuffer);

You're almost there:

"Returns:
The datagram's source address, or null if this channel is in
non-blocking mode and no datagram was immediately available"

http://download.oracle.com/javase/6...gramChannel.html#receive(java.nio.ByteBuffer)

In other words: you just need to change the line into

final SocketAddress sender = dc.receive(socketBuffer);

and be done.
}
}


Here is the code snippet for the Sender
=======================================

class CWriteDatagramChannel {
DatagramChannel dc = DatagramChannel.open().configureBlocking(false);

public CWriteDatagramChannel (int port, Selector selector) {
dc.socket().setReuseAddress(true);
dc.socket().bind(new InetSocketAddress(port));
dc.register(selector, SelectionKey.OP_READ, this);
}

/* This method gets invoked from the Selector on the isWritable() */
pubic void processWrite (ByteBuffer writeBuffer, String host, int
port) {
// I cannot do dc.socket().write since the blocking is false.
dc.send(writeBuffer, new InetSocketAddress (host, port));
}
}


Is there a way to know the Sender after the receive call in the
Reader?

See above.

Kind regards

robert
 
B

Bala

You're almost there:

"Returns:
The datagram's source address, or null if this channel is in
non-blocking mode and no datagram was immediately available"

http://download.oracle.com/javase/6/docs/api/java/nio/channels/Datagr...)

In other words: you just need to change the line into

final SocketAddress sender = dc.receive(socketBuffer);

and be done.















See above.

Kind regards

        robert


Hey Robert,
Thanks a ton for that. Really stupid on my part to not have checked
the return value of receive :D.

Thanks again
Bala
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top