I am having trouble with this combination: I would like to bind both my sending and receiving datagram channels to system-picked port and IP (not loopback and not localhost). In the following example, this works all fine when I use "old I/O" aka DatagramSocket
(case 1), but it fails with NoRouteToHostException
using NIO aka DatagramChannel
(case 3).
My API is all based around InterruptibleChannel
and the socket created via new DatagramSocket
doesn't have a channel associated, so I need to get this working with DatagramChannel.open()
. A stupid workaround is case 2, where I temporarily "connect" the channel. So this might help answer why case 3 fails...
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
public class Test {
public static void main( String[] args ) {
try { test(); } catch( Exception e ) { e.printStackTrace(); }
}
public static void test() throws IOException {
DatagramChannel tgt = DatagramChannel.open();
tgt.socket().bind( new InetSocketAddress( 0 ));
SocketAddress tgtAddr = tgt.socket().getLocalSocketAddress();
byte[] data = new byte[] { 1, 2, 3, 4 };
System.out.println( "Sending 1..." ); // ok!
DatagramSocket src1 = new DatagramSocket( new InetSocketAddress( 0 ));
src1.send( new DatagramPacket( data, data.length, tgtAddr ));
System.out.println( "Sending 2..." ); // ok!
DatagramChannel src2 = DatagramChannel.open();
src2.socket().bind( new InetSocketAddress( 0 ));
src2.connect( tgtAddr );
ByteBuffer b = ByteBuffer.wrap( data );
src2.write( b );
src2.disconnect();
System.out.println( "Sending 3..." ); // fails!
DatagramChannel src3 = DatagramChannel.open();
src3.socket().bind( new InetSocketAddress( 0 ));
src3.socket().send( new DatagramPacket( data, data.length, tgtAddr ));
}
}
You're trying to send to the address that 'tgt' is bound to, which is the wildcard address. I'm surprised that it works at all. You have to supply a proper target IP address, not 0.0.0.0.