我在使用这种组合时遇到了问题:我想将我的发送和接收数据报通道绑定到系统选择的端口和 IP(不是环回也不是localhost)。在下面的示例中,当我使用“旧 I/O”aka DatagramSocket
(案例 1)时一切正常,但NoRouteToHostException
使用 NIO aka DatagramChannel
(案例 3)失败。
我的 API 全部基于,InterruptibleChannel
并且通过创建的套接字new DatagramSocket
没有关联的通道,因此我需要使用DatagramChannel.open()
. 一个愚蠢的解决方法是案例 2,我暂时“连接”频道。因此,这可能有助于回答案例 3 失败的原因……
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 ));
}
}