0

この組み合わせで問題が発生しました。送信データグラムチャネルと受信データグラムチャネルの両方を、システムが選択したポートとIP(ループバックでもローカルホストでもないにバインドしたいと思います。次の例では、「古いI / O」別名(ケース1)を使用するとこれはすべて正常に機能しますが、 NIO別名(ケース3)を使用すると失敗します。DatagramSocketNoRouteToHostExceptionDatagramChannel

私の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 ));
   }
}
4

1 に答える 1

1

'tgt'がバインドされているアドレス(ワイルドカードアドレス)に送信しようとしています。私はそれがまったく機能することに驚いています。0.0.0.0ではなく、適切なターゲットIPアドレスを指定する必要があります。

于 2011-09-16T10:05:11.543 に答える