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
>
>