1. ホーム

[解決済み】Javaで現在のマシンのIPアドレスを取得する

2022-04-29 02:10:49

質問

異なるシステム、または同じシステム上の異なるポートで実行される異なるノードがあるシステムを開発しようとしています。

今、すべてのノードは、ブートストラップ・ノードと呼ばれる特別なノードのIPをターゲットIPとするソケットを作成します。次に、各ノードは自分自身の ServerSocket で、接続の待ち受けを開始します。

ブートストラップ・ノードはノードのリストを保持し、クエリーされるとそれらを返します。

さて、私が必要とするのは、ノードがブートストラップ・ノードにそのIPを登録しなければならないことです。私は cli.getInetAddress() に接続すると、クライアントは ServerSocket のブートストラップ・ノードですが、これはうまくいきませんでした。

  1. クライアントにPPP IPがあれば登録してほしい。
  2. それ以外の場合は、利用可能であればLANのIPを使用します。
  3. それ以外の場合は、同じコンピュータであると仮定して、127.0.0.1を登録する必要があります。

コードを使って

System.out.println(Inet4Address.getLocalHost().getHostAddress());

または

System.out.println(InetAddress.getLocalHost().getHostAddress());

私のPPP接続のIPアドレスは 117.204.44.192 ですが、上記は 192.168.1.2 を返しています。

EDIT

以下のコードを使用しています。

Enumeration e = NetworkInterface.getNetworkInterfaces();
while(e.hasMoreElements())
{
    NetworkInterface n = (NetworkInterface) e.nextElement();
    Enumeration ee = n.getInetAddresses();
    while (ee.hasMoreElements())
    {
        InetAddress i = (InetAddress) ee.nextElement();
        System.out.println(i.getHostAddress());
    }
}

に関連付けられているすべての IP アドレスを取得することができます。 NetworkInterface しかし、どのようにそれらを区別するのですか?これは私が得ている出力です。

127.0.0.1
192.168.1.2
192.168.56.1
117.204.44.19

解決方法は?

import java.net.DatagramSocket;
import java.net.InetAddress;

try(final DatagramSocket socket = new DatagramSocket()){
  socket.connect(InetAddress.getByName("8.8.8.8"), 10002);
  ip = socket.getLocalAddress().getHostAddress();
}

この方法は、複数のネットワーク・インターフェイスがある場合に有効です。常に優先される送信IPを返します。送信先 8.8.8.8 は到達可能である必要はない。

Connect UDPソケットの場合、次のような効果があります: 送信/受信の宛先を設定し、他のアドレスからのパケットをすべて破棄します。これには、システムのルーティングテーブルに従って宛先へのルートの存在を確認し、それに応じてローカルエンドポイントを設定することも含まれます。最後の部分は公式には文書化されていないようですが、BerkeleyソケットAPI(UDP "connected"状態の副作用)の不可欠の特徴のようで、WindowsとLinuxの両方で、バージョンやディストリビューションを問わず確実に機能するようです。

つまり、このメソッドは、指定されたリモートホストに接続するために使用されるローカルアドレスを提供します。実際の接続は確立されていないため、指定されたリモートIPは到達不能になる可能性があります。

編集する

として マコムギル が言うように、MacOSの場合はこれができます。

Socket socket = new Socket();
socket.connect(new InetSocketAddress("google.com", 80));
System.out.println(socket.getLocalAddress());