Here is my workaround, if you could use it in MINA please feel free to
do so. It's pretty general, and my initial tests show that it scales
to 1, 10, and 100 threads and stays at about 10,000 calls per second
total with each number of threads. If you don't synchronize and
instead create and close new sockets each time, it drops to 1,000 ...
so I think this way is best.

It's better than waiting for Sun at least :)

-Greg

---------- BEGIN SOURCE ----------

        private DatagramSocket localAddressResolverSocket;

        public synchronized InetAddress getLocalAddress(InetAddress
remoteAddress) throws IOException
        {
                if(localAddressResolverSocket == null)
                {
                        localAddressResolverSocket = new DatagramSocket(new
InetSocketAddress(AvailablePortFinder.getNextAvailable()));
                }
                
                SocketAddress remoteSocketAddress = new 
InetSocketAddress(remoteAddress, 0);

                InetAddress localAddress = null;

                localAddressResolverSocket.connect(remoteSocketAddress);

                localAddress = localAddressResolverSocket.getLocalAddress();

                localAddressResolverSocket.disconnect();

                return localAddress;
        }

---------- END SOURCE ----------

On 3/8/06, Greg Duffy <[EMAIL PROTECTED]> wrote:
> Yeah that's my current problem :(
>
> I noticed that the Sun bug (for SocketChannel) was marked fixed in a
> mustang beta, so I downloaded the latest mustang build and tried it
> out. It turns out that the issue is fixed in mustang for
> SocketChannel, but not for DatagramChannel.
>
> So I filed a bug with Sun about DatagramChannel, but I don't think
> that this will be a very expedient method of dealing with the problem,
> though.
>
> My only possible workaround at this point is to use a DatagramSocket
> (which behaves correctly, and changes the local address from the
> wildcard after connect) to scope out the local address before I
> connect. Otherwise, this is a showstopper for me since the protocol
> I'm working with requires the local address to be sent in-payload for
> routing purposes. Also, our particular use case requires multihomed
> hosts, which means I can't just query the local host address via the
> InetAddress class. When the message goes out, I need to know the bound
> address of the interface it is actually travelling through.
>
> Well, thanks for looking into this Trustin, and if you think of
> anything else please do let me know.
>
> -Greg
>
> PS: Here's the test case I submitted to Sun, just in case it helps
> anyone else out:
>
> ---------- BEGIN SOURCE ----------
> import java.io.IOException;
> import java.net.DatagramSocket;
> import java.net.InetSocketAddress;
> import java.nio.channels.DatagramChannel;
>
> public class DatagramChannelTest
> {
>         public static void main(String[] args) throws IOException
>         {
>                 final InetSocketAddress remoteAddress = new 
> InetSocketAddress("localhost", 0);
>                 InetSocketAddress localAddress = null;
>
>                 DatagramSocket socket = new DatagramSocket(8888);
>                 socket.connect(remoteAddress);
>                 localAddress = (InetSocketAddress) 
> socket.getLocalSocketAddress();
>
>                 // Expected: DatagramSocket local address: localhost:8888
>                 System.out.println("DatagramSocket local address: " +
> localAddress.getHostName() + ":" + localAddress.getPort());
>                 socket.close();
>
>                 DatagramChannel channel1 = DatagramChannel.open();
>                 channel1.connect(remoteAddress);
>                 localAddress = (InetSocketAddress) 
> channel1.socket().getLocalSocketAddress();
>
>                 // Expected: DatagramChannel #1 local address: localhost:?
>                 System.out.println("DatagramChannel #1 local address: " +
> localAddress.getHostName() + ":" + localAddress.getPort());
>
>                 channel1.close();
>
>                 DatagramChannel channel2 = DatagramChannel.open();
>                 channel2.socket().bind(new InetSocketAddress(9999));
>                 channel2.connect(remoteAddress);
>                 localAddress = (InetSocketAddress) 
> channel2.socket().getLocalSocketAddress();
>
>                 // Expected: DatagramChannel #2 local address: localhost:9999
>                 System.out.println("DatagramChannel #2 local address: " +
> localAddress.getHostName() + ":" + localAddress.getPort());
>
>                 channel2.close();
>         }
> }
> ---------- END SOURCE ----------
>
> On 3/8/06, Trustin Lee <[EMAIL PROTECTED]> wrote:
> > On 3/9/06, Trustin Lee <[EMAIL PROTECTED]> wrote:
> > >
> > > I think we can work around this issue by caching local address, too.
> > > Please let me know which transport type is a problem.  Is DatagramChannel
> > > the only issue?
> > >
> >
> > No it's not possible if a user binds to 0.0.0.0 (all devices).  So it's a
> > JDK issue unfortunately.
> >
> > 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
> >
> >
>

Reply via email to