Hello Trustin,

I ran the code on Windows XP jdk 1.6 , and this is the output I got:

Local host: kweenie/172.29.100.104
Open: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234)
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=2 cap=2048: 00 00]
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=1 cap=2048: 00]
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=3 cap=2048: 00 00 00]
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=3 cap=2048: 00 00 00]
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=3 cap=2048: 00 00 00]
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=3 cap=2048: 00 00 00]
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=4 cap=2048: 00 00 00 00]
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=4 cap=2048: 00 00 00 00]
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=4 cap=2048: 00 00 00 00]
Received: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234),
HeapBuffer[pos=0 lim=4 cap=2048: 00 00 00 00]
Closed: (datagram, server, /172.29.100.104:5678 => /0.0.0.0:1234)
unbound

I changed the code a little bit, to be able to distinguish the messages.
Also added a sleep before the unbind, (I think there's one line missing in
your output :-)

       f1.getSession().write(ByteBuffer.allocate(1)).await();
       f1.getSession().write(ByteBuffer.allocate(2)).await();

       f2.getSession().write(ByteBuffer.allocate(3)).await();
       f2.getSession().write(ByteBuffer.allocate(4)).await();

       Thread.sleep(2000);
       acceptor.unbind();
       System.out.println("unbound");
       System.exit(0);

The messages sent to the broadcast address are received multiple times:
twice per enabled network connection.
When I enable all 4 network interfaces (LAN, wireless LAN and two virtual
ones for VMWare) I receive them 8 times !

Maarten

On 9/17/07, Trustin Lee <[EMAIL PROTECTED]> wrote:
>
> Hi,
>
> I made a lot of changes to the current datagram implementation in
> trunk.  DatagramAcceptor now collaborates with DatagramConnector to
> create connected datagram socket which listens to the remote address
> of the received packet.  The following is simplified description of
> flow:
>
> * DatagramAcceptor's underlying DatagramChannel.receive is invoked
> * Once data is received, new connected datagram session is created
> using DatagramConnector.connect(receivedRemoteAddress,
> acceptor.getLocalAddress()).  If there's already a session instance
> associated with the remote address, it's reused.
>
> The advantages of this implementation are:
>
> * The acceptor-side datagram sessions can perform much better in
> multi-core environment.
> * There's no need for IoSessionRecycler on the acceptor-side anymore.
> You have full control over disconnection; probably using sessionIdle
> event in most cases.
> * Code duplication can be reduced once again, and most part of the
> existing acceptor code can be extracted into a generic acceptor
> implementation.
>
> The disadvantage is that it forces you to set reuseAddress to true,
> because multiple datagram channels are bound to the same local
> address.
>
> In Linux, connected datagram channels have priority over unconnected
> channels, so most traffic will go directly into DatagramConnector's
> NIOProcessors.  The only exception I've found is broadcast packets. It
> is always received from the unconnected channel in DatagramAcceptor.
> DatagramAcceptor immediately forwards the event to an appropriate
> session that DatagramConnector is managing, or creates a new session
> using connect().
>
> I think this behavior won't have any big differences among different
> platforms (e.g. Windows and SUNOS).  As long as multiple datagram
> channels can be bound to the same local address, this implementation
> should work fine.  To make this sure, please run the following test
> code in your machine, and let me know what the result is:
>
> -------- CODE BEGINS --------
> package net.gleamynode.tmp;
>
> import java.net.InetAddress;
> import java.net.InetSocketAddress;
>
> import org.apache.mina.common.ByteBuffer;
> import org.apache.mina.common.ConnectFuture;
> import org.apache.mina.common.IoHandlerAdapter;
> import org.apache.mina.common.IoSession;
> import org.apache.mina.transport.socket.nio.DatagramAcceptor;
> import org.apache.mina.transport.socket.nio.DatagramConnector;
>
> public class Main {
>
>     private static final int SERVER_PORT = 1234;
>     private static final int CLIENT_PORT = 5678;
>
>     public static void main(String args[]) throws Exception {
>         DatagramAcceptor acceptor = new DatagramAcceptor();
>         acceptor.setLocalAddress(new InetSocketAddress(SERVER_PORT));
>         acceptor.setHandler(new IoHandlerAdapter() {
>             @Override
>             public void sessionOpened(IoSession session) {
>                 System.out.println("Open: " + session);
>             }
>
>             @Override
>             public void sessionClosed(IoSession session) {
>                 System.out.println("Closed: " + session);
>             }
>
>             @Override
>             public void messageReceived(IoSession session, Object o) {
>                 System.out.println("Received: " + session + ", " + o);
>             }
>         });
>         acceptor.bind();
>
>         DatagramConnector connector = new DatagramConnector();
>         connector.getSessionConfig().setReuseAddress(true);
>         connector.setHandler(new IoHandlerAdapter() {
>             @Override
>             public void messageReceived(IoSession session, Object o) {
>                 System.out.println("ERR?");
>             }
>         });
>
>         // Print the local host.
>         System.out.println("Local host: " + InetAddress.getLocalHost());
>
>         // Try point-to-point.
>         ConnectFuture f1 = connector.connect(
>                 new InetSocketAddress(
>                         InetAddress.getLocalHost(), SERVER_PORT),
>                 new InetSocketAddress(
>                         InetAddress.getLocalHost(), CLIENT_PORT));
>         f1.await();
>
>
>         f1.getSession().write(ByteBuffer.allocate(1)).await();
>         f1.getSession().write(ByteBuffer.allocate(1)).await();
>
>
>         // Try broadcast.
>         ConnectFuture f2 = connector.connect(
>                 new InetSocketAddress(
>                         "255.255.255.255", SERVER_PORT),
>                 new InetSocketAddress(
>                         InetAddress.getLocalHost(), CLIENT_PORT));
>
>         f2.await();
>         f2.getSession().write(ByteBuffer.allocate(1)).await();
>         f2.getSession().write(ByteBuffer.allocate(1)).await();
>
>         acceptor.unbind();
>
>         System.exit(0);
>     }
> }
> -------- CODE ENDS --------
>
> The expected result is:
>
> -------- RESULT BEGINS --------
> Local host: primary/127.0.0.1
> Open: (datagram, server, /127.0.0.1:5678 => /0:0:0:0:0:0:0:0:1234)
> Received: (datagram, server, /127.0.0.1:5678 =>
> /0:0:0:0:0:0:0:0:1234), HeapBuffer[pos=0 lim=1 cap=2048: 00]
> Received: (datagram, server, /127.0.0.1:5678 =>
> /0:0:0:0:0:0:0:0:1234), HeapBuffer[pos=0 lim=1 cap=2048: 00]
> Received: (datagram, server, /127.0.0.1:5678 =>
> /0:0:0:0:0:0:0:0:1234), HeapBuffer[pos=0 lim=1 cap=2048: 00]
> Closed: (datagram, server, /127.0.0.1:5678 => /0:0:0:0:0:0:0:0:1234)
> -------- RESULT ENDS --------
>
> If this test fails on any platform that runs Java 5, I am doomed to
> revert my changes. :)
>
> Trustin
> --
> what we call human nature is actually human habit
> --
> http://gleamynode.net/
> --
> PGP Key ID: 0x0255ECA6
>

Reply via email to