Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #9150 > unrolled thread

Retrieving Sender Information From A Non-blocking DatagramChannel

Started byBala <r.balaji.iyer@gmail.com>
First post2011-10-24 12:14 -0700
Last post2011-10-24 14:42 -0700
Articles 3 — 2 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Retrieving Sender Information From A Non-blocking DatagramChannel Bala <r.balaji.iyer@gmail.com> - 2011-10-24 12:14 -0700
    Re: Retrieving Sender Information From A Non-blocking DatagramChannel Robert Klemme <shortcutter@googlemail.com> - 2011-10-24 22:41 +0200
      Re: Retrieving Sender Information From A Non-blocking DatagramChannel Bala <r.balaji.iyer@gmail.com> - 2011-10-24 14:42 -0700

#9150 — Retrieving Sender Information From A Non-blocking DatagramChannel

FromBala <r.balaji.iyer@gmail.com>
Date2011-10-24 12:14 -0700
SubjectRetrieving Sender Information From A Non-blocking DatagramChannel
Message-ID<dde9af14-7d8d-45ae-8864-ab5eab3610b9@i19g2000yqa.googlegroups.com>
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?


[toc] | [next] | [standalone]


#9152

FromRobert Klemme <shortcutter@googlemail.com>
Date2011-10-24 22:41 +0200
Message-ID<9gm0s4FjsaU1@mid.individual.net>
In reply to#9150
On 24.10.2011 21:14, Bala wrote:
> 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/docs/api/java/nio/channels/DatagramChannel.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

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

[toc] | [prev] | [next] | [standalone]


#9155

FromBala <r.balaji.iyer@gmail.com>
Date2011-10-24 14:42 -0700
Message-ID<0371aeff-32b2-4448-b71b-e91178f4cf38@f16g2000yqk.googlegroups.com>
In reply to#9152
On Oct 24, 4:41 pm, Robert Klemme <shortcut...@googlemail.com> wrote:
> On 24.10.2011 21:14, Bala wrote:
>
>
>
>
>
>
>
>
>
> > 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/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.
>
>
>
>
>
>
>
>
>
> >    }
> > }
>
> > 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
>
> --
> remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestpractices.com/


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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web