JavaでWi-FiインターフェースのIPv4アドレスを取得する方法

モバイルデバイスのホットスポット経由でQRコード認証を実現する際、従来のローカルIP取得メソッドでは不十分でした。特に、ノートPCのループバックアドレスや仮想ネットワークインターフェースを返すだけでは、外部デバイスからのアクセスが不可能です。この問題を解決するには、実際の無線LAN(Wi-Fi)インターフェースの有効なIPv4アドレスを動的に特定する必要があります。

JavaのNetworkInterfaceクラスを使用して、すべてのネットワークインターフェースを列挙し、Wi-Fiに該当するインターフェースを識別します。一般的に、AndroidやWindowsのWi-Fiインターフェース名はwlanwifi、またはethで始まることが多いため、名前でフィルタリングします。

package com.awe.awesometakeout.util;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

public class WifiAddressFetcher {

    public static String findWifiIpv4Address() {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            
            while (interfaces.hasMoreElements()) {
                NetworkInterface iface = interfaces.nextElement();
                
                // Wi-Fiインターフェースの名前を検出(多言語・OS対応)
                String name = iface.getName().toLowerCase();
                if (!name.contains("wlan") && !name.contains("wifi") && !name.contains("eth")) {
                    continue;
                }

                Enumeration<InetAddress> addresses = iface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress addr = addresses.nextElement();
                    
                    // IPv4アドレスかつローカルループバックでないものを選択
                    if (addr instanceof java.net.Inet4Address && !addr.isLoopbackAddress() && !addr.isLinkLocalAddress()) {
                        return addr.getHostAddress();
                    }
                }
            }
        } catch (Exception e) {
            // ログ出力または監視用に適切に処理することを推奨
            System.err.println("Wi-Fiアドレス取得中にエラー: " + e.getMessage());
        }
        
        return null;
    }
}

このメソッドは、ループバックアドレスやリンクローカルアドレス(169.254.x.x)を除外し、実際のネットワークに割り当てられたIPv4アドレスのみを返します。これにより、外部デバイスからアクセス可能なIPが得られます。

次に、この機能をQRコード生成ロジックに組み込みます。従来のgetLocalIP()を置き換え、Wi-FiアドレスをURLに使用します。

@PostMapping("/qrcode")
public void generateQrCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");

    String tempId = request.getParameter("tempId");
    if (tempId == null) {
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        return;
    }

    // Wi-Fiの有効なIPv4アドレスを取得
    String wifiIp = WifiAddressFetcher.findWifiIpv4Address();
    if (wifiIp == null) {
        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Wi-Fi IPが取得できません");
        return;
    }

    int uuid = RandomUtils.generateRandomNumber(6);
    String loginUrl = "http://" + wifiIp + ":8080/dologin?qrid=" + tempId + "&uuid=" + uuid;

    response.setContentType("text/plain");
    response.getWriter().write(loginUrl);
}

この実装により、スマートフォンのホットスポット経由でPC上のアプリにアクセス可能なQRコードが生成されます。ただし、ファイアウォールの設定(例:ポート8080の受信ルール)が適切に構成されていないと、外部デバイスからの接続は拒否されます。Windowsでは「Windows Defender ファイアウォール」で「受信ルール」を追加し、TCPポート8080を許可する必要があります。

タグ: Java NetworkInterface IPv4 Wi-Fi QRcode

8月3日 07:51 投稿