รับที่อยู่ IP ของเครื่องปัจจุบันโดยใช้ Java


291

ฉันพยายามที่จะพัฒนาระบบที่มีโหนดต่าง ๆ ที่ทำงานบนระบบที่แตกต่างกันหรือบนพอร์ตที่ต่างกันในระบบเดียวกัน

ตอนนี้โหนดทั้งหมดสร้างซ็อกเก็ตที่มี IP เป้าหมายเป็น IP ของโหนดพิเศษที่รู้จักกันในชื่อโหนดบูตสแตรปปิ้ง จากนั้นโหนดจะสร้างขึ้นเองServerSocketและเริ่มฟังการเชื่อมต่อ

โหนด bootstrapping เก็บรักษารายการของโหนดและส่งคืนพวกเขาเมื่อถูกสอบถาม

ตอนนี้สิ่งที่ฉันต้องการคือโหนดจะต้องลงทะเบียน IP กับโหนด bootstrapping ฉันลองใช้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());

ที่อยู่ IP การเชื่อมต่อ PPP ของฉันคือ: 117.204.44.192 แต่ข้างบนส่งคืนฉัน 192.168.1.2

แก้ไข

ฉันกำลังใช้รหัสต่อไปนี้:

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

Inet4Address.getLocalHost () ควรทำงานถูกต้องหรือไม่
เซียร์อินเดีย

3
ข้างในลูปถ้าฉันเพิ่ม n.isPointToPoint () จะใช้งานได้หรือไม่ ความคิดของฉันคือการกลับ "127.0.0.1" ถ้าไม่พบเครือข่ายแบบจุดต่อจุด จะใช้งานได้หรือไม่
sasidhar

3
@sasidhar: โปรดอย่าโพสต์ที่อยู่ IP ของแท้ เขียน 117.xxx.xxx.xxx สำหรับ IP ส่วนตัวที่ไม่เป็นไร
nIcE cOw

@GandandBali ขอบคุณสำหรับคำแนะนำ แต่ IP ของฉันเป็น IP แบบไดนามิกและฉันได้รับ IP ใหม่ทุกครั้งที่ฉันตัดการเชื่อมต่อและเชื่อมต่ออินเทอร์เน็ตของฉัน ดังนั้นไม่น่าจะมีปัญหาฉันเดา
sasidhar

2
ที่เกี่ยวข้อง: stackoverflow.com/questions/6064510/…
AlikElzin-kilaka

คำตอบ:


116
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 มีผลดังต่อไปนี้: มันกำหนดปลายทางสำหรับ Send / Recv, ทิ้งแพ็กเก็ตทั้งหมดจากที่อยู่อื่นและ - ซึ่งเป็นสิ่งที่เราใช้ - ถ่ายโอนซ็อกเก็ตเข้าสู่สถานะ "เชื่อมต่อ" ตั้งค่าฟิลด์ที่เหมาะสม ซึ่งรวมถึงการตรวจสอบการมีอยู่ของเส้นทางไปยังปลายทางตามตารางเส้นทางของระบบและการตั้งค่าจุดสิ้นสุดภายในเครื่องให้สอดคล้องกัน ส่วนสุดท้ายดูเหมือนว่าจะไม่มีเอกสารอย่างเป็นทางการ แต่ดูเหมือนว่าลักษณะสำคัญของ Berkeley sockets API (ผลข้างเคียงของสถานะ "เชื่อมต่อ" ของ UDP) ที่ทำงานได้อย่างน่าเชื่อถือทั้งใน Windows และ Linux ในเวอร์ชันและการแจกแจง

ดังนั้นวิธีนี้จะให้ที่อยู่ในท้องถิ่นที่จะใช้ในการเชื่อมต่อกับโฮสต์ระยะไกลที่ระบุ ไม่มีการเชื่อมต่อจริงที่สร้างขึ้นดังนั้น IP ระยะไกลที่ระบุจึงไม่สามารถเข้าถึงได้

แก้ไข:

As @macomgilพูดว่าสำหรับ MacOS คุณสามารถทำได้:

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

7
มันทำงานให้ฉันใน linux แต่ใน OsX ฉันได้รับ: "0.0.0.0"
Radu Toader

@ Jeef คำตอบที่ได้รับการปรับปรุง หากมันใช้ไม่ได้กับ OsX คุณต้องเลือกวิธีอื่น
Mr.Wang จาก Next Door

1
ยอดเยี่ยม! FYI เมื่อจัดการกับเครือข่ายภายในที่ปิดเพียงแค่แทนที่ 8.8.8.8 ด้วยบางสิ่งที่ทุก ๆ โฮสต์สามารถเข้าถึงได้
Murphy Ng

ทำงานบน Windows; เราจะยืนยันได้ว่า OSX ยังคงมีปัญหาอยู่หรือไม่?
ตอนจบ

4
@trilogy ฉันยังคงได้รับ 0.0.0.0 ใน OSX
Peter Tutervai

273

นี่อาจเป็นเรื่องยุ่งยากเล็กน้อยในกรณีทั่วไปที่สุด

บนใบหน้าของมันInetAddress.getLocalHost()ควรให้ที่อยู่ IP ของโฮสต์นี้ ปัญหาคือโฮสต์อาจมีเน็ตเวิร์กอินเตอร์เฟสจำนวนมากและอินเตอร์เฟสอาจเชื่อมโยงกับที่อยู่ IP มากกว่าหนึ่งแห่ง และนอกเหนือจากนั้นที่อยู่ IP ทั้งหมดจะสามารถเข้าถึงได้จากนอกเครื่องหรือ LAN ของคุณ ตัวอย่างเช่นอาจเป็นที่อยู่ IP สำหรับอุปกรณ์เครือข่ายเสมือนที่อยู่ IP ของเครือข่ายส่วนตัวและอื่น ๆ

สิ่งนี้หมายความว่าที่อยู่ IP ที่ส่งคืนโดยInetAddress.getLocalHost()อาจไม่ถูกต้องที่จะใช้

คุณจัดการกับสิ่งนี้ได้อย่างไร

  • วิธีหนึ่งคือการใช้NetworkInterface.getNetworkInterfaces()เพื่อให้ได้อินเทอร์เฟซเครือข่ายทั้งหมดที่รู้จักบนโฮสต์แล้ววนซ้ำที่อยู่ของแต่ละ NI
  • อีกวิธีหนึ่งคือการรับ FQDN ที่โฆษณาภายนอกจากโฮสต์และใช้InetAddress.getByName()เพื่อค้นหาที่อยู่ IP หลัก (แต่คุณจะรับได้อย่างไรและคุณจัดการกับ load balancer ที่ใช้ DNS ได้อย่างไร)
  • ชุดรูปแบบของรุ่นก่อนหน้าคือรับ FQDN ที่ต้องการจากไฟล์ปรับแต่งหรือพารามิเตอร์บรรทัดคำสั่ง
  • อีกรูปแบบหนึ่งคือรับที่อยู่ IP ที่ต้องการจากไฟล์ปรับแต่งหรือพารามิเตอร์บรรทัดคำสั่ง

โดยสรุปแล้วInetAddress.getLocalHost()จะใช้งานได้ แต่คุณอาจต้องระบุวิธีการอื่นสำหรับกรณีที่โค้ดของคุณทำงานในสภาพแวดล้อมที่มีเครือข่าย "ซับซ้อน"


ฉันสามารถรับที่อยู่ IP ทั้งหมดที่เกี่ยวข้องกับการเชื่อมต่อเครือข่ายทั้งหมด แต่ฉันจะแยกความแตกต่างได้อย่างไร

  • ที่อยู่ใด ๆ ในช่วง 127.xxx.xxx.xxx คือที่อยู่ "loopback" จะปรากฏเฉพาะกับโฮสต์ "นี้" เท่านั้น
  • ที่อยู่ใด ๆ ในช่วง 192.168.xxx.xxx เป็นที่อยู่ IP ส่วนตัว (หรือที่รู้จักในพื้นที่ไซต์) สิ่งเหล่านี้สงวนไว้สำหรับใช้ภายในองค์กร เช่นเดียวกับที่อยู่ 10.xxx.xxx.xxx และ 172.16.xxx.xxx ถึง 172.31.xxx.xxx
  • ที่อยู่ในช่วง 169.254.xxx.xxx คือที่อยู่ IP ของการเชื่อมโยงท้องถิ่น สิ่งเหล่านี้สงวนไว้สำหรับใช้ในส่วนเครือข่ายเดียว
  • ที่อยู่ในช่วง 224.xxx.xxx.xxx ถึง 239.xxx.xxx.xxx เป็นที่อยู่แบบหลายผู้รับ
  • ที่อยู่ 255.255.255.255 คือที่อยู่การออกอากาศ
  • สิ่งอื่นใดควรเป็นที่อยู่ IPv4 สาธารณะแบบจุดต่อจุดที่ถูกต้อง

ในความเป็นจริง InetAddress API มีวิธีการทดสอบลูปแบ็คลิงค์โลคัลไซต์โลคอลมัลติคาสต์และแอดเดรสบรอดคาสต์ คุณสามารถใช้สิ่งเหล่านี้เพื่อจัดเรียงที่อยู่ IP ที่คุณได้รับกลับมาให้เหมาะสมที่สุด


3
ในกรณีที่ใคร ๆ ก็อยากรู้ getLocalHost ทำการค้นหา DNS บนชื่อโฮสต์ของเซิร์ฟเวอร์เป็นหลัก หากได้รับที่อยู่ IP จากการค้นหานั้นระบบจะค้นหาส่วนต่อประสานที่มีอยู่เพื่อดูว่าส่วนต่อประสานใดมีที่อยู่ IP นั้นและส่งคืนส่วนต่อประสานนั้น ซึ่งหมายความว่า getLocalHost จะมีแนวโน้มที่จะทำงานในสภาพแวดล้อม "เซิร์ฟเวอร์" โดยที่ IP ขาออกเป็นโดเมนที่จับคู่กับชื่อโฮสต์ของเซิร์ฟเวอร์
Pace

1
บน Ubuntu 14.04 API นี้ส่งคืน 127.0.1.1 แม้ว่า ifconfig จะรายงานเพียงสองอินเทอร์เฟซหนึ่งที่ฉันต้องการ (ที่อยู่ IP สาธารณะที่เข้าถึงได้) และลูปแบ็ค (127.0.0.1) แปลกที่มันส่งคืนนามแฝงลูปแบ็คอื่น
ctpenrose

ฉันจะเพิ่มว่าถ้าคุณuse getLocalHost().getHostAddress()จะเผยแพร่บางสิ่งคุณอาจเห็น0.0.0.0เมื่อมองจากคอมพิวเตอร์ nother บนเครือข่าย นี่คือคำอธิบายที่นี่นี่คือสิ่งที่เกิดขึ้นกับฉันเมื่อฉันใช้Gazeboกับคอมพิวเตอร์สองเครื่อง
Peter Mitrano

57

โพสต์ที่นี่ทดสอบรหัสแก้ปัญหาความกำกวม IP จากhttps://issues.apache.org/jira/browse/JCS-40 (InetAddress.getLocalHost () คลุมเครือบนระบบ Linux):

/**
 * Returns an <code>InetAddress</code> object encapsulating what is most likely the machine's LAN IP address.
 * <p/>
 * This method is intended for use as a replacement of JDK method <code>InetAddress.getLocalHost</code>, because
 * that method is ambiguous on Linux systems. Linux systems enumerate the loopback network interface the same
 * way as regular LAN network interfaces, but the JDK <code>InetAddress.getLocalHost</code> method does not
 * specify the algorithm used to select the address returned under such circumstances, and will often return the
 * loopback address, which is not valid for network communication. Details
 * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4665037">here</a>.
 * <p/>
 * This method will scan all IP addresses on all network interfaces on the host machine to determine the IP address
 * most likely to be the machine's LAN address. If the machine has multiple IP addresses, this method will prefer
 * a site-local IP address (e.g. 192.168.x.x or 10.10.x.x, usually IPv4) if the machine has one (and will return the
 * first site-local address if the machine has more than one), but if the machine does not hold a site-local
 * address, this method will return simply the first non-loopback address found (IPv4 or IPv6).
 * <p/>
 * If this method cannot find a non-loopback address using this selection algorithm, it will fall back to
 * calling and returning the result of JDK method <code>InetAddress.getLocalHost</code>.
 * <p/>
 *
 * @throws UnknownHostException If the LAN address of the machine cannot be found.
 */
private static InetAddress getLocalHostLANAddress() throws UnknownHostException {
    try {
        InetAddress candidateAddress = null;
        // Iterate all NICs (network interface cards)...
        for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
            NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
            // Iterate all IP addresses assigned to each card...
            for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
                InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
                if (!inetAddr.isLoopbackAddress()) {

                    if (inetAddr.isSiteLocalAddress()) {
                        // Found non-loopback site-local address. Return it immediately...
                        return inetAddr;
                    }
                    else if (candidateAddress == null) {
                        // Found non-loopback address, but not necessarily site-local.
                        // Store it as a candidate to be returned if site-local address is not subsequently found...
                        candidateAddress = inetAddr;
                        // Note that we don't repeatedly assign non-loopback non-site-local addresses as candidates,
                        // only the first. For subsequent iterations, candidate will be non-null.
                    }
                }
            }
        }
        if (candidateAddress != null) {
            // We did not find a site-local address, but we found some other non-loopback address.
            // Server might have a non-site-local address assigned to its NIC (or it might be running
            // IPv6 which deprecates the "site-local" concept).
            // Return this non-loopback candidate address...
            return candidateAddress;
        }
        // At this point, we did not find a non-loopback address.
        // Fall back to returning whatever InetAddress.getLocalHost() returns...
        InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
        if (jdkSuppliedAddress == null) {
            throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
        }
        return jdkSuppliedAddress;
    }
    catch (Exception e) {
        UnknownHostException unknownHostException = new UnknownHostException("Failed to determine LAN address: " + e);
        unknownHostException.initCause(e);
        throw unknownHostException;
    }
}

6
จะต้องมีการตั้งข้อสังเกตว่าสิ่งนี้ยังคงไม่สามารถแก้ปัญหาความกำกวมได้ในกรณีที่โฮสต์มีอินเทอร์เฟซที่คล้ายกันหลายอย่าง
Vadzim

1
คำตอบที่ร้องดีกว่า - stackoverflow.com/questions/9481865/… ได้รับที่อยู่ IP ท้องถิ่นที่ใช้เป็น src สำหรับ Default Gatway
Radu Toader

เหตุใดจึงเพิ่มที่อยู่ IP ด้วยเครื่องหมายทับด้านหน้า .. เช่น /10.39.0.17 .. ?, มันควรจะถูกตัดด้วยวิธีนี้หรือไม่?
Kanagavelu Sugumar

51

คุณสามารถใช้คลาสInetAddressของ java เพื่อจุดประสงค์นี้

InetAddress IP=InetAddress.getLocalHost();
System.out.println("IP of my system is := "+IP.getHostAddress());

เอาท์พุทสำหรับระบบของฉัน = IP of my system is := 10.100.98.228

getHostAddress ()ส่งคืน

ส่งคืนสตริงที่อยู่ IP ในงานนำเสนอที่เป็นข้อความ

หรือคุณสามารถทำได้

InetAddress IP=InetAddress.getLocalHost();
System.out.println(IP.toString());

เอาท์พุท = IP of my system is := RanRag-PC/10.100.98.228


9
โปรดทราบว่า 10.xxx เป็นที่อยู่ส่วนตัวแสดงว่าระบบของคุณอยู่ในเครือข่าย NAT จะปรากฏเป็นที่อยู่อื่นเมื่อติดต่อกับโลกภายนอก หากคุณต้องการที่อยู่ IP ภายนอกจริง ๆ คุณจะต้องติดต่อหนึ่งในหลาย ๆ เว็บไซต์ซึ่งจะสะท้อนกลับไปยังที่อยู่ IP ที่คุณมาจากคุณ สิ่งนี้อาจเป็นประโยชน์กับคุณหรือไม่ก็ได้ ระบบของคุณแทบจะไม่สามารถเข้าถึงได้จากภายนอกในกรณีใด ๆ
Edward Falk

19

เมื่อคุณกำลังมองหาที่อยู่ "ท้องถิ่น" ของคุณคุณควรทราบว่าเครื่องแต่ละเครื่องไม่เพียง แต่มีเครือข่ายอินเทอร์เฟซเดียวและแต่ละอินเทอร์เฟซอาจมีอยู่ภายในเครื่องของตนเอง ซึ่งหมายความว่าเครื่องของคุณมีที่อยู่ "ท้องถิ่น" หลายแห่งเสมอ

ที่อยู่ "ท้องถิ่น" ที่แตกต่างกันจะถูกเลือกให้ใช้โดยอัตโนมัติเมื่อคุณเชื่อมต่อกับปลายทาง ตัวอย่างเช่นเมื่อคุณเชื่อมต่อgoogle.comคุณกำลังใช้ที่อยู่ท้องถิ่น "นอก" แต่เมื่อคุณเชื่อมต่อกับที่localhostอยู่ในพื้นที่ของคุณจะเป็นของlocalhostตัวเองเสมอ

ด้านล่างแสดงวิธีค้นหาที่อยู่ในพื้นที่ของคุณเมื่อคุณกำลังสื่อสารกับgoogle.com:

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

เยี่ยมมาก !! - ง่ายมาก :)
smilyface

4
เพิ่ม socket.close () ที่ส่วนท้าย :)
MC

11

ตัวอย่างใน scala (มีประโยชน์ในไฟล์ sbt):

  import collection.JavaConverters._
  import java.net._

  def getIpAddress: String = {

    val enumeration = NetworkInterface.getNetworkInterfaces.asScala.toSeq

    val ipAddresses = enumeration.flatMap(p =>
      p.getInetAddresses.asScala.toSeq
    )

    val address = ipAddresses.find { address =>
      val host = address.getHostAddress
      host.contains(".") && !address.isLoopbackAddress
    }.getOrElse(InetAddress.getLocalHost)

    address.getHostAddress
  }

10

แก้ไข 1: โค้ดที่อัปเดตตั้งแต่ลิงก์ก่อนหน้านี้ไม่มีอยู่อีกต่อไป

import java.io.*;
import java.net.*;

public class GetMyIP {
    public static void main(String[] args) {
        URL url = null;
        BufferedReader in = null;
        String ipAddress = "";
        try {
            url = new URL("http://bot.whatismyipaddress.com");
            in = new BufferedReader(new InputStreamReader(url.openStream()));
            ipAddress = in.readLine().trim();
            /* IF not connected to internet, then
             * the above code will return one empty
             * String, we can check it's length and
             * if length is not greater than zero, 
             * then we can go for LAN IP or Local IP
             * or PRIVATE IP
             */
            if (!(ipAddress.length() > 0)) {
                try {
                    InetAddress ip = InetAddress.getLocalHost();
                    System.out.println((ip.getHostAddress()).trim());
                    ipAddress = (ip.getHostAddress()).trim();
                } catch(Exception exp) {
                    ipAddress = "ERROR";
                }
            }
        } catch (Exception ex) {
            // This try will give the Private IP of the Host.
            try {
                InetAddress ip = InetAddress.getLocalHost();
                System.out.println((ip.getHostAddress()).trim());
                ipAddress = (ip.getHostAddress()).trim();
            } catch(Exception exp) {
                ipAddress = "ERROR";
            }
            //ex.printStackTrace();
        }
        System.out.println("IP Address: " + ipAddress);
    }
}

เวอร์ชั่นจริง: สิ่งนี้หยุดทำงาน

หวังว่าตัวอย่างข้อมูลนี้อาจช่วยให้คุณประสบความสำเร็จ:

// Method to get the IP Address of the Host.
private String getIP()
{
    // This try will give the Public IP Address of the Host.
    try
    {
        URL url = new URL("http://automation.whatismyip.com/n09230945.asp");
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
        String ipAddress = new String();
        ipAddress = (in.readLine()).trim();
        /* IF not connected to internet, then
         * the above code will return one empty
         * String, we can check it's length and
         * if length is not greater than zero, 
         * then we can go for LAN IP or Local IP
         * or PRIVATE IP
         */
        if (!(ipAddress.length() > 0))
        {
            try
            {
                InetAddress ip = InetAddress.getLocalHost();
                System.out.println((ip.getHostAddress()).trim());
                return ((ip.getHostAddress()).trim());
            }
            catch(Exception ex)
            {
                return "ERROR";
            }
        }
        System.out.println("IP Address is : " + ipAddress);

        return (ipAddress);
    }
    catch(Exception e)
    {
        // This try will give the Private IP of the Host.
        try
        {
            InetAddress ip = InetAddress.getLocalHost();
            System.out.println((ip.getHostAddress()).trim());
            return ((ip.getHostAddress()).trim());
        }
        catch(Exception ex)
        {
            return "ERROR";
        }
    }
}

2
วิธีแก้ปัญหาจะใช้งานได้หวังว่าถ้าฉันเชื่อมต่อกับอินเทอร์เน็ตเสมอ แต่ฉันไม่รับประกัน นอกจากนี้เมื่อระบบไม่ได้เชื่อมต่อกับอินเทอร์เน็ตแล้วฉันต้องกลับ LAN ที่อยู่ IP ของระบบถ้ามีมิฉะนั้นโฮสต์ท้องถิ่น ดังนั้นไม่ใช่ตัวเลือกที่เป็นไปได้สำหรับฉัน วิธีอื่นใด ??
sasidhar

@sasidhar: เมื่อคุณเชื่อมต่อกับอินเทอร์เน็ตมีเพียงคุณเท่านั้นที่มี IP สาธารณะของคุณฉันเดาว่าถ้าคุณไม่ได้เชื่อมต่อวิธีนี้จะให้ IP ท้องถิ่นหรือ LAN IP ของคุณและเงื่อนไขสุดท้ายตามที่คุณกำหนด คุณสามารถส่งคืน "127.0.0.1" แทนการส่งคืนข้อผิดพลาด
nIcE cOw

1
ฉันชอบแนวทางของคุณ แต่ลิงค์นั้นดูเหมือนจะไม่ทำงานอีกต่อไป !! ฉันสามารถวางตัวควบคุมบนระบบของตัวเองให้ทำงานแทนลิงค์ภายนอกนั้นและเชื่อถือได้มากกว่าหรือไม่?
azerafati

1
@Blream: ขอบคุณมากที่นำสิ่งนี้มาให้ความรู้ของฉันลิงก์ไม่ทำงานอีกต่อไป ฉันได้อัปเดตโพสต์ด้วยอินพุตใหม่แล้ว หวังว่ามันจะทำงานได้ดีกับ usercase ของคุณ เกี่ยวกับคำถามของคุณฉันไม่รู้จริงๆว่าจะตั้งค่าคอนโทรลเลอร์ในระบบของคุณเองอย่างไรเพื่อให้ทำงานได้ ดังนั้นฉันจะไม่สามารถให้ข้อมูลเชิงลึกเกี่ยวกับหัวข้อนี้ BAD ของฉัน ขอขอบคุณอีกครั้งและรักษารอยยิ้ม :-)
nIcE cOw

1
มากพอ ๆ กับนี่คือทางออกที่ยอดเยี่ยมมันไม่น่าเชื่อถืออย่างยิ่ง หากคุณต้องบล็อกเธรดหลัก (สมมติว่ามี) และไม่ว่าด้วยเหตุผลใดก็ตามwhatismyip.comแอพของคุณจะหยุดทำงาน :( หรือจะส่งคืนข้อมูลขยะและทำให้เกิดพฤติกรรมที่ไม่คาดคิด ที่อยู่ IP ส่วนใหญ่ที่ตรวจพบโดยwhatismyip.comไม่จำเป็นต้องเป็นที่อยู่ IP ของเครื่องที่คุณใช้
ถอดรหัส

6

ก่อนอื่นนำเข้าชั้นเรียน

import java.net.InetAddress;

ในชั้นเรียน

  InetAddress iAddress = InetAddress.getLocalHost();
  String currentIp = iAddress.getHostAddress();
  System.out.println("Current IP address : " +currentIp); //gives only host address

2
มันให้ที่อยู่ IP แรกเท่านั้นแม้ว่าจะไม่ได้ใช้งาน!
Yahya


5
private static InetAddress getLocalAddress(){
        try {
            Enumeration<NetworkInterface> b = NetworkInterface.getNetworkInterfaces();
            while( b.hasMoreElements()){
                for ( InterfaceAddress f : b.nextElement().getInterfaceAddresses())
                    if ( f.getAddress().isSiteLocalAddress())
                        return f.getAddress();
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return null;
    }

1
โปรดพิจารณาเพิ่มคำอธิบายบางอย่างเกี่ยวกับสิ่งที่รหัสของคุณทำ
HCarrasko

4

นี่เป็นตัวอย่างการทำงานของคำตอบที่ยอมรับข้างต้น! คลาส NetIdentity นี้จะเก็บทั้ง ip โฮสต์ภายในเช่นเดียวกับการวนรอบท้องถิ่น หากคุณอยู่บนเซิร์ฟเวอร์ที่ใช้ DNS ดังกล่าวข้างต้นคุณอาจต้องเพิ่มการตรวจสอบเพิ่มเติมหรือไปที่เส้นทางไฟล์การกำหนดค่า

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

/**
 * Class that allows a device to identify itself on the INTRANET.
 * 
 * @author Decoded4620 2016
 */
public class NetIdentity {

    private String loopbackHost = "";
    private String host = "";

    private String loopbackIp = "";
    private String ip = "";
    public NetIdentity(){

        try{
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();

            while(interfaces.hasMoreElements()){
                NetworkInterface i = interfaces.nextElement();
                if(i != null){
                    Enumeration<InetAddress> addresses = i.getInetAddresses();
                    System.out.println(i.getDisplayName());
                    while(addresses.hasMoreElements()){
                        InetAddress address = addresses.nextElement();
                        String hostAddr = address.getHostAddress();

                        // local loopback
                        if(hostAddr.indexOf("127.") == 0 ){
                            this.loopbackIp = address.getHostAddress();
                            this.loopbackHost = address.getHostName();
                        }

                        // internal ip addresses (behind this router)
                        if( hostAddr.indexOf("192.168") == 0 || 
                                hostAddr.indexOf("10.") == 0 || 
                                hostAddr.indexOf("172.16") == 0 ){
                            this.host = address.getHostName();
                            this.ip = address.getHostAddress();
                        }


                        System.out.println("\t\t-" + address.getHostName() + ":" + address.getHostAddress() + " - "+ address.getAddress());
                    }
                }
            }
        }
        catch(SocketException e){

        }
        try{
            InetAddress loopbackIpAddress = InetAddress.getLocalHost();
            this.loopbackIp = loopbackIpAddress.getHostName();
            System.out.println("LOCALHOST: " + loopbackIp);
        }
        catch(UnknownHostException e){
            System.err.println("ERR: " + e.toString());
        }
    }

    public String getLoopbackHost(){
        return loopbackHost;
    }

    public String getHost(){
        return host;
    }
    public String getIp(){
        return ip;
    }
    public String getLoopbackIp(){
        return loopbackIp;
    }
}

เมื่อฉันเรียกใช้รหัสนี้จริง ๆ แล้วฉันได้รับการพิมพ์ออกมาเช่นนี้:

    Software Loopback Interface 1
        -127.0.0.1:127.0.0.1 - [B@19e1023e
        -0:0:0:0:0:0:0:1:0:0:0:0:0:0:0:1 - [B@7cef4e59
Broadcom 802.11ac Network Adapter
        -VIKING.yourisp.com:192.168.1.142 - [B@64b8f8f4
        -fe80:0:0:0:81fa:31d:21c9:85cd%wlan0:fe80:0:0:0:81fa:31d:21c9:85cd%wlan0 - [B@2db0f6b2
Microsoft Kernel Debug Network Adapter
Intel Edison USB RNDIS Device
Driver for user-mode network applications
Cisco Systems VPN Adapter for 64-bit Windows
VirtualBox Host-Only Ethernet Adapter
        -VIKING:192.168.56.1 - [B@3cd1f1c8
        -VIKING:fe80:0:0:0:d599:3cf0:5462:cb7%eth4 - [B@3a4afd8d
LogMeIn Hamachi Virtual Ethernet Adapter
        -VIKING:25.113.118.39 - [B@1996cd68
        -VIKING:2620:9b:0:0:0:0:1971:7627 - [B@3339ad8e
        -VIKING:fe80:0:0:0:51bf:994d:4656:8486%eth5 - [B@555590
Bluetooth Device (Personal Area Network)
        -fe80:0:0:0:4c56:8009:2bca:e16b%eth6:fe80:0:0:0:4c56:8009:2bca:e16b%eth6 - [B@3c679bde
Bluetooth Device (RFCOMM Protocol TDI)
Intel(R) Ethernet Connection (2) I218-V
        -fe80:0:0:0:4093:d169:536c:7c7c%eth7:fe80:0:0:0:4093:d169:536c:7c7c%eth7 - [B@16b4a017
Microsoft Wi-Fi Direct Virtual Adapter
        -fe80:0:0:0:103e:cdf0:c0ac:1751%wlan1:fe80:0:0:0:103e:cdf0:c0ac:1751%wlan1 - [B@8807e25
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0000
VirtualBox Host-Only Ethernet Adapter-WFP Native MAC Layer LightWeight Filter-0000
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0001
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0002
VirtualBox Host-Only Ethernet Adapter-VirtualBox NDIS Light-Weight Filter-0000
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0003
VirtualBox Host-Only Ethernet Adapter-QoS Packet Scheduler-0000
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0004
VirtualBox Host-Only Ethernet Adapter-WFP 802.3 MAC Layer LightWeight Filter-0000
VirtualBox Host-Only Ethernet Adapter-HHD Software NDIS 6.0 Filter Driver-0005
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0000
Intel(R) Ethernet Connection (2) I218-V-WFP Native MAC Layer LightWeight Filter-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0001
Intel(R) Ethernet Connection (2) I218-V-Shrew Soft Lightweight Filter-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0002
Intel(R) Ethernet Connection (2) I218-V-VirtualBox NDIS Light-Weight Filter-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0003
Intel(R) Ethernet Connection (2) I218-V-QoS Packet Scheduler-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0004
Intel(R) Ethernet Connection (2) I218-V-WFP 802.3 MAC Layer LightWeight Filter-0000
Intel(R) Ethernet Connection (2) I218-V-HHD Software NDIS 6.0 Filter Driver-0005
Broadcom 802.11ac Network Adapter-WFP Native MAC Layer LightWeight Filter-0000
Broadcom 802.11ac Network Adapter-Virtual WiFi Filter Driver-0000
Broadcom 802.11ac Network Adapter-Native WiFi Filter Driver-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0003
Broadcom 802.11ac Network Adapter-Shrew Soft Lightweight Filter-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0004
Broadcom 802.11ac Network Adapter-VirtualBox NDIS Light-Weight Filter-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0005
Broadcom 802.11ac Network Adapter-QoS Packet Scheduler-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0006
Broadcom 802.11ac Network Adapter-WFP 802.3 MAC Layer LightWeight Filter-0000
Broadcom 802.11ac Network Adapter-HHD Software NDIS 6.0 Filter Driver-0007
Microsoft Wi-Fi Direct Virtual Adapter-WFP Native MAC Layer LightWeight Filter-0000
Microsoft Wi-Fi Direct Virtual Adapter-Native WiFi Filter Driver-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0002
Microsoft Wi-Fi Direct Virtual Adapter-Shrew Soft Lightweight Filter-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0003
Microsoft Wi-Fi Direct Virtual Adapter-VirtualBox NDIS Light-Weight Filter-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0004
Microsoft Wi-Fi Direct Virtual Adapter-QoS Packet Scheduler-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0005
Microsoft Wi-Fi Direct Virtual Adapter-WFP 802.3 MAC Layer LightWeight Filter-0000
Microsoft Wi-Fi Direct Virtual Adapter-HHD Software NDIS 6.0 Filter Driver-0006

สำหรับการใช้งานของฉันฉันกำลังตั้งค่าเซิร์ฟเวอร์ Upnp มันช่วยให้เข้าใจ 'รูปแบบ' ที่ฉันกำลังมองหา บางส่วนของวัตถุที่ส่งคืนคืออะแดปเตอร์อีเธอร์เน็ตอะแดปเตอร์เครือข่ายอะแดปเตอร์เครือข่ายเสมือนไดรเวอร์และอะแดปเตอร์ไคลเอนต์ VPN ไม่ใช่ทุกอย่างที่มีที่อยู่เช่นกัน ดังนั้นคุณจะต้องข้ามวัตถุอินเทอร์เฟซที่ไม่มี

คุณยังสามารถเพิ่มสิ่งนี้ลงในลูปของกระแสได้ NetworkInterface i

while(interfaces.hasMoreElements()){
    Enumeration<InetAddress> addresses = i.getInetAddresses();
    System.out.println(i.getDisplayName());
    System.out.println("\t- name:" + i.getName());
    System.out.println("\t- idx:" + i.getIndex());
    System.out.println("\t- max trans unit (MTU):" + i.getMTU());
    System.out.println("\t- is loopback:" + i.isLoopback());
    System.out.println("\t- is PPP:" + i.isPointToPoint());
    System.out.println("\t- isUp:" + i.isUp());
    System.out.println("\t- isVirtual:" + i.isVirtual());
    System.out.println("\t- supportsMulticast:" + i.supportsMulticast());
}

และคุณจะเห็นข้อมูลในผลลัพธ์ของคุณเช่นนี้:

Software Loopback Interface 1
    - name:lo
    - idx:1
    - max trans unit (MTU):-1
    - is loopback:true
    - is PPP:false
    - isUp:true
    - isVirtual:false
    - supportsMulticast:true
        -ADRESS: [127.0.0.1(VIKING-192.168.56.1)]127.0.0.1:127.0.0.1 - [B@19e1023e
        -ADRESS: [0:0:0:0:0:0:0:1(VIKING-192.168.56.1)]0:0:0:0:0:0:0:1:0:0:0:0:0:0:0:1 - [B@7cef4e59
Broadcom 802.11ac Network Adapter
    - name:wlan0
    - idx:2
    - max trans unit (MTU):1500
    - is loopback:false
    - is PPP:false
    - isUp:true
    - isVirtual:false
    - supportsMulticast:true
        -ADRESS: [VIKING.monkeybrains.net(VIKING-192.168.56.1)]VIKING.monkeybrains.net:192.168.1.142 - [B@64b8f8f4
        -ADRESS: [fe80:0:0:0:81fa:31d:21c9:85cd%wlan0(VIKING-192.168.56.1)]fe80:0:0:0:81fa:31d:21c9:85cd%wlan0:fe80:0:0:0:81fa:31d:21c9:85cd%wlan0 - [B@2db0f6b2
Microsoft Kernel Debug Network Adapter
    - name:eth0
    - idx:3
    - max trans unit (MTU):-1
    - is loopback:false
    - is PPP:false
    - isUp:false
    - isVirtual:false
    - supportsMulticast:true

3

ใช้InetAddress.getLocalHost ()เพื่อรับที่อยู่ในเครื่อง

import java.net.InetAddress;

try {
  InetAddress addr = InetAddress.getLocalHost();            
  System.out.println(addr.getHostAddress());
} catch (UnknownHostException e) {
}

ที่อยู่ IP ของการเชื่อมต่อ PPP ของฉันคือ: 117.204.44.192 แต่ข้างบนส่งคืนฉัน 192.168.1.2
sasidhar

คุณต้องรวบรวมข้อมูลอินสแตนซ์ InetAddress ทั้งหมดที่มีอยู่และหาว่าอันไหนเหมาะสม
ถอดรหัส

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

public class IpAddress {

NetworkInterface ifcfg;
Enumeration<InetAddress> addresses;
String address;

public String getIpAddress(String host) {
    try {
        ifcfg = NetworkInterface.getByName(host);
        addresses = ifcfg.getInetAddresses();
        while (addresses.hasMoreElements()) {
            address = addresses.nextElement().toString();
            address = address.replace("/", "");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return ifcfg.toString();
}
}

1

วิธีการค่อนข้างง่ายที่ดูเหมือนว่าจะทำงาน ...

String getPublicIPv4() throws UnknownHostException, SocketException{
    Enumeration<NetworkInterface> e = NetworkInterface.getNetworkInterfaces();
    String ipToReturn = null;
    while(e.hasMoreElements())
    {
        NetworkInterface n = (NetworkInterface) e.nextElement();
        Enumeration<InetAddress> ee = n.getInetAddresses();
        while (ee.hasMoreElements())
        {
            InetAddress i = (InetAddress) ee.nextElement();
            String currentAddress = i.getHostAddress();
            logger.trace("IP address "+currentAddress+ " found");
            if(!i.isSiteLocalAddress()&&!i.isLoopbackAddress() && validate(currentAddress)){
                ipToReturn = currentAddress;    
            }else{
                System.out.println("Address not validated as public IPv4");
            }

        }
    }

    return ipToReturn;
}

private static final Pattern IPv4RegexPattern = Pattern.compile(
        "^(([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");

public static boolean validate(final String ip) {
    return IPv4RegexPattern.matcher(ip).matches();
}

1

นี่จะได้รับที่อยู่ IP ของเครือข่ายของคุณหากเครื่องของคุณเป็นส่วนหนึ่งของเครือข่าย

try {
    System.out.println(InetAddress.getLocalHost().getHostAddress());
} catch (UnknownHostException e) {
    e.printStackTrace();
}

0

โดยปกติเมื่อฉันพยายามค้นหาที่อยู่ IP สาธารณะของฉันเช่นcmyip.comหรือwww.iplocation.netฉันใช้วิธีนี้:

public static String myPublicIp() {

    /*nslookup myip.opendns.com resolver1.opendns.com*/
    String ipAdressDns  = "";
    try {
        String command = "nslookup myip.opendns.com resolver1.opendns.com";
        Process proc = Runtime.getRuntime().exec(command);

        BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream()));

        String s;
        while ((s = stdInput.readLine()) != null) {
            ipAdressDns  += s + "\n";
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    return ipAdressDns ;
}

0

เนื่องจากระบบของฉัน (เช่นระบบอื่น ๆ มากมาย) จึงมีอินเตอร์เฟสเครือข่ายที่หลากหลาย InetAddress.getLocalHost()หรือInet4Address.getLocalHost()แค่คืนสิ่งที่ฉันไม่ต้องการ ดังนั้นฉันต้องใช้วิธีการไร้เดียงสานี้

InetAddress[] allAddresses = Inet4Address.getAllByName("YourComputerHostName");
        InetAddress desiredAddress;
        //In order to find the desired Ip to be routed by other modules (WiFi adapter)
        for (InetAddress address :
                allAddresses) {
            if (address.getHostAddress().startsWith("192.168.2")) {
                desiredAddress = address;
            }
        }
// Use the desired address for whatever purpose.

เพียงระวังว่าในวิธีนี้ฉันรู้แล้วว่าที่อยู่ IP ที่ฉันต้องการนั้นอยู่ใน192.168.2ซับเน็ต


-1
public static String getIpAddress() {

    String ipAddress = null;

    try {
        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();

        while (networkInterfaces.hasMoreElements()) {

            NetworkInterface networkInterface = networkInterfaces.nextElement();

            byte[] hardwareAddress = networkInterface.getHardwareAddress();
            if (null == hardwareAddress || 0 == hardwareAddress.length || (0 == hardwareAddress[0] && 0 == hardwareAddress[1] && 0 == hardwareAddress[2])) continue;

            Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();

            if (inetAddresses.hasMoreElements()) ipAddress = inetAddresses.nextElement().toString();

            break;
        }
    } catch (SocketException e) {
        e.printStackTrace();
    }

    return ipAddress;
}

โปรดเพิ่มคำอธิบายบางอย่างเกี่ยวกับรหัสของคุณ
HCarrasko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.