You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Dani Eichhorn <da...@squix.ch> on 2006/02/23 17:31:37 UTC

[mina] Sending datagrams without connection

I'm new to mina, so please excuse me, if this is a stupid question,  
since the mail list archive seems to be broken...

In java.nio I have the choice if I want to send a datagram using a  
connection, or if I'm using the DatagramChannel.recieve/send methods.  
Do I have this choice in Mina as well, since it is built on top of  
java.nio...
I'm working on a library for NAT traversal (UDP and TCP) for P2P  
networks. For a NAT traversal technique called hole punching I need  
to be able to send datagrams into the blue, without getting any  
response in the first place. It works directly with java.nio, but I'd  
like to use the convenience of mina...

Cheers
Dani

Re: [mina] Sending datagrams without connection

Posted by "이희승 (Trustin Lee)" <tr...@gmail.com>.
2008-02-09 (토), 13:06 -0600, David M. Lloyd 쓰시길:
> David M. Lloyd wrote:
> > Wilson Yeung wrote:
> >> It would be quite nice to be able to do something equivalent to 
> >> sendto() with
> >> a DatagramAcceptor or a DatagramConnector.
> >>
> >> I've written a UDP application based on Mina that sends precisely 1 
> >> packet
> >> to 1 million end points, and waits for 1 packet from 1 million end 
> >> points. Each 2 packet exchange is 1 Mina IoSession, and I continuously 
> >> reuse the
> >> same 1000 - 5000 prebound IoSession objects, that is, I keep 1000 - 
> >> 5000 of
> >> these exchanges in flight at a time.
> > 
> > My opinion is that there should simply be one IoSession for all datagram
> > sockets.
> 
> Let me clarify - I mean one IoSession for *each* datagram socket.

David and I met in the JBossWorld 2008 and had some time to discuss
about this issue, and the following is my idea after the discussion with
him.

If we map one IoSession to one DatagramChannel, it means we need to
provide additional information (i.e. remoteAddress of the received
message) when messageReceived event is fired.  There are a few solutions
to this issue:

1) Add SocketAddress parameter to messageReceived - it's not so good
because TCP/IP transports will never use it.
2) Change the datagram transport to use other type than IoBuffer.  For
example, provide a class that contains an IoBuffer and SocketAddress -
it's also not so good because it breaks backward compatibility and
prevents a user from migrating from TCP to UDP and vice versa.  Their
IoHandler implementation will not be reusable.

Another problem is that we already have IoSession.getRemoteAddress().
If we map one session to one datagram channel,
DatagramSession.getRemoteAddress() should return something ambiguous
such as null, which causes backward compatibility issues.

Actually, having more than one sessions per datagram channel is similar
to the solution #2 above in that IoSession behaves a kind of wrapper of
an extra information.  The problem here is the creation and destruction
overhead of DatagramSessions.

So... I'd like to suggest to keep the current API while minimizing
creation overhead.  We definitely need to improve performance for
datagram transport and see if how it compares to the plain NIO
implementation.  If the performance tuning attempt fails, we could think
about revamping the overall API which might be pain to users.

-- 
Trustin Lee - Principal Software Engineer, JBoss, Red Hat
--
what we call human nature is actually human habit
--
http://gleamynode.net/

Re: [mina] Sending datagrams without connection

Posted by "David M. Lloyd" <da...@redhat.com>.
David M. Lloyd wrote:
> Wilson Yeung wrote:
>> It would be quite nice to be able to do something equivalent to 
>> sendto() with
>> a DatagramAcceptor or a DatagramConnector.
>>
>> I've written a UDP application based on Mina that sends precisely 1 
>> packet
>> to 1 million end points, and waits for 1 packet from 1 million end 
>> points. Each 2 packet exchange is 1 Mina IoSession, and I continuously 
>> reuse the
>> same 1000 - 5000 prebound IoSession objects, that is, I keep 1000 - 
>> 5000 of
>> these exchanges in flight at a time.
> 
> My opinion is that there should simply be one IoSession for all datagram
> sockets.

Let me clarify - I mean one IoSession for *each* datagram socket.

- DML


Re: [mina] Sending datagrams without connection

Posted by "이희승 (Trustin Lee)" <tr...@gmail.com>.
2008-02-09 (토), 13:04 -0600, David M. Lloyd 쓰시길:
> Wilson Yeung wrote:
> > It would be quite nice to be able to do something equivalent to sendto() with
> > a DatagramAcceptor or a DatagramConnector.
> > 
> > I've written a UDP application based on Mina that sends precisely 1 packet
> > to 1 million end points, and waits for 1 packet from 1 million end points. 
> > Each 2 packet exchange is 1 Mina IoSession, and I continuously reuse the
> > same 1000 - 5000 prebound IoSession objects, that is, I keep 1000 - 5000 of
> > these exchanges in flight at a time.

How frequently are the messages exchanged?  If it's less than once a
minute, you could create a ExpiringIoSessionRecycler with longer
timeout, which will decrease the overhead of session creation due to
unnecessary timeout.

> My opinion is that there should simply be one IoSession for all datagram
> sockets.  MINA cannot have a valid notion of a session because the underlying
> protocol might not have such a notion.  Creating IoSessions for every packet
> or pair of packets is supremely wasteful.

I agree.  I even think this is an API design flaw which is very
difficult to fix without revamping the API.  It's mainly because MINA
designed after TCP/IP model in its early stage.  To implement UDP/IP
support, I had to mimic the connection management using
IoSessionRecycler.  It might be the time to think about the way to fix
the flaw.  The change will be pretty big and will look like a whole new
API though.

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/

Re: [mina] Sending datagrams without connection

Posted by "David M. Lloyd" <da...@redhat.com>.
Wilson Yeung wrote:
> It would be quite nice to be able to do something equivalent to sendto() with
> a DatagramAcceptor or a DatagramConnector.
> 
> I've written a UDP application based on Mina that sends precisely 1 packet
> to 1 million end points, and waits for 1 packet from 1 million end points. 
> Each 2 packet exchange is 1 Mina IoSession, and I continuously reuse the
> same 1000 - 5000 prebound IoSession objects, that is, I keep 1000 - 5000 of
> these exchanges in flight at a time.

My opinion is that there should simply be one IoSession for all datagram
sockets.  MINA cannot have a valid notion of a session because the underlying
protocol might not have such a notion.  Creating IoSessions for every packet
or pair of packets is supremely wasteful.

- DML


Re: [mina] Sending datagrams without connection

Posted by Wilson Yeung <wi...@gmail.com>.
It would be quite nice to be able to do something equivalent to sendto() with
a DatagramAcceptor or a DatagramConnector.

I've written a UDP application based on Mina that sends precisely 1 packet
to 1 million end points, and waits for 1 packet from 1 million end points. 
Each 2 packet exchange is 1 Mina IoSession, and I continuously reuse the
same 1000 - 5000 prebound IoSession objects, that is, I keep 1000 - 5000 of
these exchanges in flight at a time.

Profiling the application showed me that it spends 60% of its CPU time in
the newSession() call.  I need to create a session per remote end point, so
that's 1 million calls to DatagramAcceptor.newSession(), and it hurts.

I used to do this with DatagramConnector.connect(), but this was 2 times
slower than the current implementation using DatagramAcceptor.

It would be nice to be able to send the packet and not bind with the remote
destination first, and would probably double my performance.  And
performance is very, very important to me in this application.



Trustin Lee wrote:
> 
> 
>> In java.nio I have the choice if I want to send a datagram using a
>> connection, or if I'm using the DatagramChannel.recieve/send methods.
>> Do I have this choice in Mina as well, since it is built on top of
>> java.nio...
> 
> 
> For now, you have to bind first:
> 
> InetSocketAddress address = new InetSocketAddress( 8080 );
> IoAcceptor acceptor = new DatagramAcceptor();
> acceptor.bind( address, handler );
> IoSession session = acceptor.newSession( address, new InetSocketAddress( "
> remote.host.com", 8080 ) );
> session.write( ... );
> 
> If you don't want to bind, there's no such way yet.  Please let us know if
> this becomes a problem.  This means we need to modify our API to fill the
> abstraction hole.
> 
> 

-- 
View this message in context: http://www.nabble.com/Re%3A--mina--Sending-datagrams-without-connection-tp7520296s16868p15385247.html
Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.


Re: [mina] Sending datagrams without connection

Posted by Dani Eichhorn <da...@squix.ch>.
Hi Trustin

Thanks for your reply. Binding first is absolutely no problem. I  
guess I just didn't think out-of-the-box enough to find the solution  
you posted here by myself. I tried using a DatagramConnector instead,  
but your way seems to be much more efficient:

			/*
			*** Sends more or less every 0.5 seconds a UDP message to  
destination and listens to answers on the same port
			**/
			IoSession session;
			IoConnector connector = new DatagramConnector();
			ConnectFuture future = connector.connect(destination, new  
InetSocketAddress (destination.getPort()), new UDPMinaTester( ));
			
             		future.join();

			try {
				session = future.getSession();

				for(;;){

					Thread.sleep(500);
					session.write(this.message);

				}
			} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
			} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
			}

I guess the whole "future" stuff is not necessary here, since there's  
never really a connection it could wait for, is that right?

By the way: would the Mina team be interested in integrating NAT  
traversal code into to library? In one way (from app developper view)  
it's some kind of basic need, but to work it needs some kind of  
complex infrastructure, like a not NATed rendezvous server...

Thanks for your great work with MINA! I tried to implement a clean  
code for NAT traversal for several weeks, before I discovered your  
framework. Starting again clean on top of Mina made it possible to  
write good code within three days!

Cheers
Dani

Am 25.02.2006 um 10:32 schrieb Trustin Lee:

> Hi Dani,
>
> On 2/24/06, Dani Eichhorn <da...@squix.ch> wrote:
> I'm new to mina, so please excuse me, if this is a stupid question,
> since the mail list archive seems to be broken...
>
> The link to the archive on our web site was broken.  Now it's fixed.
>
> In java.nio I have the choice if I want to send a datagram using a
> connection, or if I'm using the DatagramChannel.recieve/send methods.
> Do I have this choice in Mina as well, since it is built on top of
> java.nio...
>
> For now, you have to bind first:
>
> InetSocketAddress address = new InetSocketAddress( 8080 );
> IoAcceptor acceptor = new DatagramAcceptor();
> acceptor.bind( address, handler );
> IoSession session = acceptor.newSession( address, new  
> InetSocketAddress( "remote.host.com ", 8080 ) );
> session.write( ... );
>
> If you don't want to bind, there's no such way yet.  Please let us  
> know if this becomes a problem.  This means we need to modify our  
> API to fill the abstraction hole.
>
> HTH,
> Trustin
> -- 
> what we call human nature is actually human habit
> --
> http://gleamynode.net/
> --
> PGP key fingerprints:
> * E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
> * B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6


Re: [mina] Sending datagrams without connection

Posted by Dani Eichhorn <da...@squix.ch>.
Hi Trustin

Thanks for your reply. Binding first is absolutely no problem. I  
guess I just didn't think out-of-the-box enough to find the solution  
you posted here by myself. I tried using a DatagramConnector instead,  
but your way seems to be much more efficient:

			/*
			*** Sends more or less every 0.5 seconds a UDP message to  
destination and listens to answers on the same port
			**/
			IoSession session;
			IoConnector connector = new DatagramConnector();
			ConnectFuture future = connector.connect(destination, new  
InetSocketAddress (destination.getPort()), new UDPMinaTester( ));
			
             		future.join();

			try {
				session = future.getSession();

				for(;;){

					Thread.sleep(500);
					session.write(this.message);

				}
			} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
			} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
			}

I guess the whole "future" stuff is not necessary here, since there's  
never really a connection it could wait for, is that right?

By the way: would the Mina team be interested in integrating NAT  
traversal code into to library? In one way (from app developper view)  
it's some kind of basic need, but to work it needs some kind of  
complex infrastructure, like a not NATed rendezvous server...

Thanks for your great work with MINA! I tried to implement a clean  
code for NAT traversal for several weeks, before I discovered your  
framework. Starting again clean on top of Mina made it possible to  
write good code within three days!

Cheers
Dani

Am 25.02.2006 um 10:32 schrieb Trustin Lee:

> Hi Dani,
>
> On 2/24/06, Dani Eichhorn <da...@squix.ch> wrote:
> I'm new to mina, so please excuse me, if this is a stupid question,
> since the mail list archive seems to be broken...
>
> The link to the archive on our web site was broken.  Now it's fixed.
>
> In java.nio I have the choice if I want to send a datagram using a
> connection, or if I'm using the DatagramChannel.recieve/send methods.
> Do I have this choice in Mina as well, since it is built on top of
> java.nio...
>
> For now, you have to bind first:
>
> InetSocketAddress address = new InetSocketAddress( 8080 );
> IoAcceptor acceptor = new DatagramAcceptor();
> acceptor.bind( address, handler );
> IoSession session = acceptor.newSession( address, new  
> InetSocketAddress( "remote.host.com ", 8080 ) );
> session.write( ... );
>
> If you don't want to bind, there's no such way yet.  Please let us  
> know if this becomes a problem.  This means we need to modify our  
> API to fill the abstraction hole.
>
> HTH,
> Trustin
> -- 
> what we call human nature is actually human habit
> --
> http://gleamynode.net/
> --
> PGP key fingerprints:
> * E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
> * B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6


Re: [mina] Sending datagrams without connection

Posted by Trustin Lee <tr...@gmail.com>.
Hi Dani,

On 2/24/06, Dani Eichhorn <da...@squix.ch> wrote:
>
> I'm new to mina, so please excuse me, if this is a stupid question,
> since the mail list archive seems to be broken...


The link to the archive on our web site was broken.  Now it's fixed.

In java.nio I have the choice if I want to send a datagram using a
> connection, or if I'm using the DatagramChannel.recieve/send methods.
> Do I have this choice in Mina as well, since it is built on top of
> java.nio...


For now, you have to bind first:

InetSocketAddress address = new InetSocketAddress( 8080 );
IoAcceptor acceptor = new DatagramAcceptor();
acceptor.bind( address, handler );
IoSession session = acceptor.newSession( address, new InetSocketAddress( "
remote.host.com", 8080 ) );
session.write( ... );

If you don't want to bind, there's no such way yet.  Please let us know if
this becomes a problem.  This means we need to modify our API to fill the
abstraction hole.

HTH,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: [mina] Sending datagrams without connection

Posted by Trustin Lee <tr...@gmail.com>.
Hi Dani,

On 2/24/06, Dani Eichhorn <da...@squix.ch> wrote:
>
> I'm new to mina, so please excuse me, if this is a stupid question,
> since the mail list archive seems to be broken...


The link to the archive on our web site was broken.  Now it's fixed.

In java.nio I have the choice if I want to send a datagram using a
> connection, or if I'm using the DatagramChannel.recieve/send methods.
> Do I have this choice in Mina as well, since it is built on top of
> java.nio...


For now, you have to bind first:

InetSocketAddress address = new InetSocketAddress( 8080 );
IoAcceptor acceptor = new DatagramAcceptor();
acceptor.bind( address, handler );
IoSession session = acceptor.newSession( address, new InetSocketAddress( "
remote.host.com", 8080 ) );
session.write( ... );

If you don't want to bind, there's no such way yet.  Please let us know if
this becomes a problem.  This means we need to modify our API to fill the
abstraction hole.

HTH,
Trustin
--
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6