จะรับที่อยู่ IP ของเซิร์ฟเวอร์ที่แอปพลิเคชัน C # ของฉันทำงานอยู่ได้อย่างไร


365

ฉันใช้เซิร์ฟเวอร์และฉันต้องการแสดงที่อยู่ IP ของตัวเอง

ไวยากรณ์สำหรับการรับที่อยู่ IP ของคอมพิวเตอร์ (ถ้าเป็นไปได้, ภายนอก) คืออะไร?

มีคนเขียนรหัสต่อไปนี้

IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
    if (ip.AddressFamily.ToString() == "InterNetwork")
    {
        localIP = ip.ToString();
    }
}
return localIP;

อย่างไรก็ตามโดยทั่วไปฉันไม่ไว้ใจผู้เขียนและฉันไม่เข้าใจรหัสนี้ มีวิธีที่ดีกว่าในการทำเช่นนั้น?


1
เกี่ยวกับที่อยู่ IP ภายนอกฉันไม่คิดว่าจะมีวิธีการในการกู้คืนข้อมูลนั้น localhost อาจอยู่หลังเราเตอร์ NAT ที่แปลที่อยู่เครือข่ายท้องถิ่นเป็นที่สาธารณะ มีวิธี (ท้องถิ่น) ในการตรวจสอบว่าเป็นกรณีนี้หรือไม่? ฉันไม่รู้อะไรเลย ...
Thiago Arrais

ตัวอย่างใช้ DNS เพื่อรับที่อยู่ IP ฉันมีประสบการณ์กับ DNS ที่มีข้อมูลที่ไม่ถูกต้อง สำหรับกรณีนั้นตัวอย่างสามารถตอบกลับด้วยข้อมูลที่ไม่ถูกต้อง
leiflundgren

@leiflundgren ฉันมีประสบการณ์กับ DNS ที่มีข้อมูลที่ไม่ถูกต้อง คำตอบของฉันอธิบายวิธีที่ฉันได้รับที่อยู่ IP ที่ฉันต้องการโดยไม่ต้องพึ่งพา DNS เมื่อฉันเผชิญกับสถานการณ์นั้น
ศิษย์ของ Dr. Wily

13
ใช้ LINQ:Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(o => o.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First().ToString()
Luis Perez

2
นี่เป็นสถานการณ์ทั่วไปที่ผู้ใช้ที่มีความต้องการแตกต่างกันอย่างสิ้นเชิงมักถามคำถามเดียวกัน บางคนต้องการทราบว่าคอมพิวเตอร์สามารถเข้าถึงจากเครือข่ายสาธารณะได้อย่างไร คำตอบที่ยอมรับคือSTUNแม้ว่าคำตอบจำนวนมากที่มีแฮ็กขึ้นอยู่กับบุคคลที่สามแบบสุ่ม บางคนต้องการทราบที่อยู่ IP ของพวกเขาในเครือข่ายท้องถิ่น คำตอบที่ดีในกรณีนี้พูดถึงวิธี NetworkInterface.GetAllNetworkInterfaces
Stéphane Gourichon

คำตอบ:


237

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

แก้ไข:สิ่งเดียวที่ฉันจะเปลี่ยนคือการเปลี่ยนแปลง:

if (ip.AddressFamily.ToString() == "InterNetwork")

สำหรับสิ่งนี้:

if (ip.AddressFamily == AddressFamily.InterNetwork)

ไม่จำเป็นต้องToStringทำการแจงนับเพื่อทำการเปรียบเทียบ


3
ฉันต้องการที่อยู่ IP ภายนอกถ้าเป็นไปได้ ฉันคิดว่ามันจะไม่เป็นไปได้ถ้าฉันอยู่หลัง NAT
Nefzen

3
ไม่เครื่องของคุณจะรู้ที่อยู่ NAT ของมันเท่านั้น
แอนดรูกระต่าย

1
ฉันค่อนข้างมั่นใจว่าคุณจะต้องเข้าถึงเซิร์ฟเวอร์ภายนอกสำหรับที่อยู่ภายนอก
Thiago Arrais

29
ฉันยังขอแนะนำbreakคำสั่งหลังจากที่พบว่ามีการหลีกเลี่ยงการวนซ้ำ IP เพิ่มเติมโดยไม่จำเป็น (ในกรณีนี้ฉันสงสัยว่าผลกระทบต่อประสิทธิภาพจะมีความสำคัญ แต่ฉันชอบเน้นนิสัยการเขียนโปรแกรมที่ดีโดยทั่วไป)
Eric J.

7
โปรดทราบว่าสิ่งนี้อาจล้มเหลวเมื่อเครื่องมีพอร์ต 'InterNetwork' หลายพอร์ต (ในกรณีของฉัน: การ์ดอีเธอร์เน็ตและพอร์ตเครื่องเสมือน) รหัสปัจจุบันจะให้ IP ล่าสุดแก่คุณในรายการ
Christian Studer

168

วิธีเดียวที่จะรู้ว่า IP สาธารณะของคุณคือการขอให้คนอื่นบอกคุณ รหัสนี้อาจช่วยคุณ:

public string GetPublicIP()
{
    String direction = "";
    WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
    using (WebResponse response = request.GetResponse())
    using (StreamReader stream = new StreamReader(response.GetResponseStream()))
    {
        direction = stream.ReadToEnd();
    }

    //Search for the ip in the html
    int first = direction.IndexOf("Address: ") + 9;
    int last = direction.LastIndexOf("</body>");
    direction = direction.Substring(first, last - first);

    return direction;
}

20
คุณรู้หรือไม่ว่าตัวอย่างโค้ดของคุณถูกกล่าวถึงในคำถามที่ 13 ยี่สิบคำถามที่อธิบายเกี่ยวกับ Microsoft Academy ผู้นำเสนอขออภัยที่ขโมยรหัสของคุณ ตั้งแต่ 8:30 นาทีเป็นต้นไป ดูนี่สิ :)
Erwin Rooijakkers

4
ลิงค์น่าเสียดาย
Barry Guvenkaya

ลิงค์ใหม่ในกรณีที่ทุกคนต้องการที่จะเห็นมัน
Kimmax

1
โปรดใช้ลิงก์ipof.in/txtเพื่อให้คุณสามารถรับ IP ได้โดยตรงโดยไม่ต้องใช้รหัสการแยกวิเคราะห์ HTML ทั้งหมด
vivekv

82

น้ำยาทำความสะอาดและโซลูชันครบวงจร: D

//This returns the first IP4 address or null
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);

3
ปัญหาเกี่ยวกับรหัสนี้: * ถือว่าคอมพิวเตอร์มีที่อยู่ IP เดียวเท่านั้น หลายคนมีหลายอย่าง * พิจารณาเฉพาะที่อยู่ IPV4 เพิ่ม InterNetworkV6 เพื่อรวม IPV6
Robert Bratton

1
@ RobertBratton ขอขอบคุณสำหรับการเล่นซ้ำของคุณ ปัญหาไม่ได้สันนิษฐานว่าเป็นที่อยู่ IP หลายแห่งหรือ IPV6 พร้อมการแก้ไขรหัสนี้เล็กน้อยซึ่งสามารถจัดการกับปัญหาที่แตกต่างกันได้
Mohammed A. Fadil

50

หากคุณไม่สามารถพึ่งพาที่อยู่ IP ของคุณจากเซิร์ฟเวอร์ DNS (ซึ่งเกิดขึ้นกับฉัน) คุณสามารถใช้วิธีการต่อไปนี้:

namespace ที่ System.Net.NetworkInformation มีระดับ NetworkInterfaceซึ่งมีคงวิธี GetAllNetworkInterfaces

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

หากคุณกำลังมองหาที่อยู่ IP หนึ่งแห่งคุณจะต้องกรองรายการลงไปจนกว่าคุณจะสามารถระบุที่อยู่ที่ถูกต้องได้ คุณอาจต้องทำการทดลองบางอย่าง แต่ฉันประสบความสำเร็จด้วยวิธีการต่อไปนี้:

  • กรอง NetworkInterfaces ใด ๆ OperationalStatus == OperationalStatus.Upที่ไม่ได้ใช้งานโดยตรวจสอบ สิ่งนี้จะแยกอะแดปเตอร์อีเธอร์เน็ตจริงของคุณตัวอย่างเช่นหากคุณไม่มีสายเคเบิลเครือข่าย

สำหรับแต่ละ NetworkInterface, คุณจะได้รับIPInterfacePropertiesวัตถุโดยใช้GetIPProperties วิธีการและจาก IPInterfaceProperties วัตถุที่คุณสามารถเข้าถึงUnicastAddresses คุณสมบัติสำหรับรายชื่อของUnicastIPAddressInformationวัตถุ

  • กรองที่อยู่ unicast ที่ไม่ต้องการโดยการตรวจสอบ DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred
  • กรองที่อยู่ "เสมือน" AddressPreferredLifetime != UInt32.MaxValueโดยตรวจสอบ

ณ จุดนี้ฉันใช้ที่อยู่ของที่อยู่ unicast แรก (ถ้ามี) ที่ตรงกับตัวกรองทั้งหมดเหล่านี้

แก้ไข:

[แก้ไขรหัสเมื่อวันที่ 16 พฤษภาคม 2018 เพื่อรวมเงื่อนไขที่กล่าวถึงในข้อความด้านบนสำหรับสถานะการตรวจจับที่อยู่ที่ซ้ำกันและอายุการใช้งานที่ต้องการ]

ตัวอย่างด้านล่างแสดงการกรองตามสถานะการทำงานตระกูลที่อยู่ไม่รวมที่อยู่ลูปแบ็ค (127.0.0.1) สถานะการตรวจจับที่อยู่ที่ซ้ำกันและอายุการใช้งานที่ต้องการ

static IEnumerable<IPAddress> GetLocalIpAddresses()
{
    // Get the list of network interfaces for the local computer.
    var adapters = NetworkInterface.GetAllNetworkInterfaces();

    // Return the list of local IPv4 addresses excluding the local
    // host, disconnected, and virtual addresses.
    return (from adapter in adapters
            let properties = adapter.GetIPProperties()
            from address in properties.UnicastAddresses
            where adapter.OperationalStatus == OperationalStatus.Up &&
                  address.Address.AddressFamily == AddressFamily.InterNetwork &&
                  !address.Equals(IPAddress.Loopback) &&
                  address.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred &&
                  address.AddressPreferredLifetime != UInt32.MaxValue
            select address.Address);
}

2
ในกรณีพิเศษนี้ OP ต้องการเห็นที่อยู่ IP ภายนอกของเขาดังนั้นโซลูชัน DNS น่าจะเป็นวิธีที่จะไป แต่สำหรับการทำซ้ำที่อยู่ IP ท้องถิ่นนี่เป็นวิธีที่ฉันแนะนำ
Matt Davis

3
ยอมรับว่า DNS เป็นวิธีที่ง่ายกว่าในการรับที่อยู่ IP ฉันได้กล่าวถึงคำตอบของฉันว่าวิธีนี้ใช้ได้เมื่อ DNS ของคุณไม่น่าเชื่อถือ ฉันใช้สิ่งนี้ในสภาพแวดล้อมที่ DNS มีความยุ่งเหยิงเช่นนั้นหากคุณย้ายเครื่องจากพอร์ตอีเธอร์เน็ตหนึ่งไปยังอีกพอร์ตหนึ่ง DNS จะยังคงรายงานที่อยู่ IP เก่าดังนั้นมันจึงเกือบไร้ประโยชน์สำหรับวัตถุประสงค์ของฉัน
ศิษย์ของ Dr. Wily

ฉันขอขอบคุณคำอธิบายทั้งหมด แต่คุณควรโพสต์ตัวอย่างโค้ดด้วย
Aidin

ขอบคุณมาก โปรดทราบว่าการอัพเดต Windows ล่าสุด UnicastAddresses สมมติฐานแรกไม่มีอีกต่อไป ตอนนี้ฉันต้องตรวจสอบUnicastAddress ทั้งหมดสำหรับอะแดปเตอร์แต่ละตัวด้วยการกรองเพิ่มเติมโดยใช้AddressPreferredLifetimeและDuplicateAddressDetectionStation (กล่าวถึงในข้อความของคุณด้านบน)
user3085342

37
WebClient webClient = new WebClient();
string IP = webClient.DownloadString("http://myip.ozymo.com/");

ifconfig.me/ip ใช้งานไม่ได้อีกต่อไป ลองใช้api.ipify.orgหรือลิงก์ในความคิดเห็นของดั๊กแทน
Kenny83

16
using System.Net;

string host = Dns.GetHostName();
IPHostEntry ip = Dns.GetHostEntry(host);
Console.WriteLine(ip.AddressList[0].ToString());

เพิ่งทดสอบสิ่งนี้กับเครื่องของฉันและใช้งานได้


3
มันจะได้ ip ท้องถิ่นของคุณและคำถามเกี่ยวกับ IP ภายนอกเช่นที่คุณท่องอินเทอร์เน็ต ..
Sangram Nandkhile

15

หากคุณต้องการหลีกเลี่ยงการใช้ DNS:

List<IPAddress> ipList = new List<IPAddress>();
foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
{
    foreach (var address in netInterface.GetIPProperties().UnicastAddresses)
    {
        if (address.Address.AddressFamily == AddressFamily.InterNetwork)
        {
            Console.WriteLine("found IP " + address.Address.ToString());
            ipList.Add(address.Address);
        }
    }
}

9

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

ก่อนอื่นฉันจะได้รับที่อยู่ของเราเตอร์ (เกตเวย์) ถ้ามันกลับมาว่าฉันเชื่อมต่อกับเกตเวย์ (ซึ่งหมายความว่าไม่ได้เชื่อมต่อโดยตรงกับโมเด็มไร้สายหรือไม่) จากนั้นเรามีที่อยู่เกตเวย์ของเราเป็น IP ที่อยู่อื่น .

จากนั้นเราต้องรับรายการ IPAddresses ของคอมพิวเตอร์ นี่คือสิ่งที่ไม่ยากเพราะเราเตอร์ (เราเตอร์ทั้งหมด) ใช้ 4 ไบต์ (... ) สามรายการแรกมีความสำคัญที่สุดเนื่องจากคอมพิวเตอร์ทุกเครื่องที่เชื่อมต่อจะมีที่อยู่ IP4 ที่ตรงกับสามไบต์แรก เช่น 192.168.0.1 เป็นมาตรฐานสำหรับ IP เริ่มต้นของเราเตอร์เว้นแต่ผู้ดูแลระบบจะเปลี่ยนแปลง '192.168.0' หรืออะไรก็ตามที่พวกเขาอาจจะเป็นสิ่งที่เราต้องการในการจับคู่ และนั่นคือทั้งหมดที่ฉันทำในฟังก์ชัน IsAddressOfGateway สาเหตุของการจับคู่ความยาวนั้นเป็นเพราะไม่ใช่ที่อยู่ทั้งหมด (ซึ่งมีไว้สำหรับคอมพิวเตอร์เท่านั้น) มีความยาว 4 ไบต์ หากคุณพิมพ์ netstat ใน cmd คุณจะพบว่าสิ่งนี้เป็นจริง ดังนั้นคุณมีมัน ใช่ใช้เวลาเพิ่มอีกนิดหน่อยเพื่อให้ได้สิ่งที่คุณต้องการจริงๆ กระบวนการกำจัด และเพื่อประโยชน์ของพระเจ้า อย่าหาที่อยู่ด้วยการส่ง Ping ซึ่งต้องใช้เวลาเพราะก่อนอื่นคุณจะส่งที่อยู่ที่จะส่ง Ping แล้วจะต้องส่งผลลัพธ์กลับมา ไม่ทำงานโดยตรงกับ. Net classes ที่จัดการกับสภาพแวดล้อมระบบของคุณและคุณจะได้รับคำตอบที่คุณต้องการเมื่อมันทำกับคอมพิวเตอร์ของคุณเพียงอย่างเดียว

ตอนนี้ถ้าคุณเชื่อมต่อโดยตรงกับโมเด็มของคุณกระบวนการเกือบจะเหมือนกันเพราะโมเด็มเป็นเกตเวย์ของคุณ แต่ submask ไม่เหมือนกันเพราะคุณได้รับข้อมูลโดยตรงจากเซิร์ฟเวอร์ DNS ของคุณผ่านโมเด็มและไม่ได้หลอกลวงโดยเราเตอร์ที่ให้บริการ อินเทอร์เน็ตถึงคุณแม้ว่าคุณจะยังสามารถใช้รหัสเดียวกันได้เพราะไบต์สุดท้ายของ IP ที่กำหนดให้กับโมเด็มคือ 1 ดังนั้นหาก IP ที่ส่งจากโมเด็มซึ่งเปลี่ยนเป็น 111.111.111.1 'คุณจะได้รับ 111.111.111 (บางส่วน ค่าไบต์) โปรดทราบว่าเราจำเป็นต้องค้นหาข้อมูลเกตเวย์เนื่องจากมีอุปกรณ์ที่จัดการกับการเชื่อมต่ออินเทอร์เน็ตมากกว่าเราเตอร์และโมเด็มของคุณ

ตอนนี้คุณเห็นแล้วว่าทำไมคุณไม่เปลี่ยนเราท์เตอร์ของคุณสองไบต์แรก 192 และ 168 สิ่งเหล่านี้มีความโดดเด่นสำหรับเราเตอร์เท่านั้นไม่ใช่การใช้อินเทอร์เน็ตหรือเราจะมีปัญหาร้ายแรงกับ IP Protocol และการกระตุกสองครั้ง ภาพที่เราเตอร์ IP ที่คุณกำหนดคือ 192.168.44.103 และคุณคลิกที่ไซต์ที่มี IP นั้นเช่นกัน พระเจ้าช่วย! คอมพิวเตอร์ของคุณจะไม่รู้ว่าจะ ping อย่างไร ชนตรงนั้น เพื่อหลีกเลี่ยงปัญหานี้เราเตอร์เท่านั้นที่จะถูกกำหนดสิ่งเหล่านี้และไม่ใช่สำหรับการใช้งานอินเทอร์เน็ต ดังนั้นปล่อยสองไบต์แรกของเราเตอร์ไว้คนเดียว

static IPAddress FindLanAddress()
{
    IPAddress gateway = FindGetGatewayAddress();
    if (gateway == null)
        return null;

    IPAddress[] pIPAddress = Dns.GetHostAddresses(Dns.GetHostName());

    foreach (IPAddress address in pIPAddress)            {
        if (IsAddressOfGateway(address, gateway))
                return address;
    return null;
}
static bool IsAddressOfGateway(IPAddress address, IPAddress gateway)
{
    if (address != null && gateway != null)
        return IsAddressOfGateway(address.GetAddressBytes(),gateway.GetAddressBytes());
    return false;
}
static bool IsAddressOfGateway(byte[] address, byte[] gateway)
{
    if (address != null && gateway != null)
    {
        int gwLen = gateway.Length;
        if (gwLen > 0)
        {
            if (address.Length == gateway.Length)
            {
                --gwLen;
                int counter = 0;
                for (int i = 0; i < gwLen; i++)
                {
                    if (address[i] == gateway[i])
                        ++counter;
                }
                return (counter == gwLen);
            }
        }
    }
    return false;

}
static IPAddress FindGetGatewayAddress()
{
    IPGlobalProperties ipGlobProps = IPGlobalProperties.GetIPGlobalProperties();

    foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
    {
        IPInterfaceProperties ipInfProps = ni.GetIPProperties();
        foreach (GatewayIPAddressInformation gi in ipInfProps.GatewayAddresses)
            return gi.Address;
    }
    return null;
}

1
สิ่งนี้ไม่สมเหตุสมผล: foreach (GatewayIPAddressInformation gi ใน ipInfProps.GatewayAddresses) ส่งคืน gi.Address;
Edwin Evans

3
ไม่มีการรับประกันว่า "คอมพิวเตอร์ใด ๆ ที่เชื่อมต่อกับเกตเวย์จะมีที่อยู่ IP4 ที่ตรงกับสามไบต์แรก" มันขึ้นอยู่กับซับเน็ตมาสก์ซึ่งสามารถมีการผสมบิตต่าง ๆ ได้ และนอกจากนี้การเริ่มต้นไบต์จะได้ไม่ต้องเป็น "192.168" ในขณะที่อธิบายไว้ที่นี่ รหัสนี้จะใช้งานได้หาก subnet mask เป็น255.255.255.0เช่นนั้นและจะทำเช่นนั้นในวิธีที่ค่อนข้างซับซ้อน IMO
Groo

8

ฉันแค่คิดว่าฉันจะเพิ่มหนึ่งซับของตัวเอง (แม้ว่าจะมีคำตอบที่มีประโยชน์อื่น ๆ อีกมากมายแล้ว)


string ipAddress = new WebClient().DownloadString("http://icanhazip.com");


4
โปรดทราบว่านี่อาจมีหน่วยความจำรั่ว WebClient ไม่ได้ถูกกำจัดอย่างถูกต้อง แต่ให้ใช้: using (var client = new WebClient ()) {return client.DownloadString (" icanhazip.com /"). Trim () ; }
FOO


4

หากคุณใช้งานอินทราเน็ตคุณจะสามารถรับที่อยู่ IP ของเครื่องในท้องถิ่นและหากไม่ใช่คุณจะได้รับที่อยู่ IP ภายนอกด้วย: เว็บ:

//this will bring the IP for the current machine on browser
System.Web.HttpContext.Current.Request.UserHostAddress

เดสก์ทอป:

//This one will bring all local IPs for the desired namespace
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());

3
namespace NKUtilities 
{
    using System;
    using System.Net;
    using System.Net.Sockets;

    public class DNSUtility
    {
        public static int Main(string [] args)
        {
            string strHostName = "";
            try {

                if(args.Length == 0)
                {
                    // Getting Ip address of local machine...
                    // First get the host name of local machine.
                    strHostName = Dns.GetHostName();
                    Console.WriteLine ("Local Machine's Host Name: " +  strHostName);
                }
                else
                {
                    // Otherwise, get the IP address of the host provided on the command line.
                    strHostName = args[0];
                }

                // Then using host name, get the IP address list..
                IPHostEntry ipEntry = Dns.GetHostEntry (strHostName);
                IPAddress [] addr = ipEntry.AddressList;

                for(int i = 0; i < addr.Length; i++)
                {
                    Console.WriteLine("IP Address {0}: {1} ", i, addr[i].ToString());
                }
                return 0;

            } 
            catch(SocketException se) 
            {
                Console.WriteLine("{0} ({1})", se.Message, strHostName);
                return -1;
            } 
            catch(Exception ex) 
            {
                Console.WriteLine("Error: {0}.", ex.Message);
                return -1;
            }
        }
    }
}

ดูที่นี่สำหรับรายละเอียด

คุณต้องจำไว้ว่าคอมพิวเตอร์ของคุณสามารถมี IP ได้มากกว่าหนึ่งอัน (อันที่จริงมันก็เป็นเช่นนั้นเสมอ) - คุณเป็นใคร


2

ลองสิ่งนี้:

 IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
 String MyIp = localIPs[0].ToString();

1
ส่งคืนที่อยู่ IP ภายในเครื่องจำนวนหนึ่งซึ่งหนึ่งในนั้นคือที่อยู่ IPv4 อย่างไรก็ตามการหาที่ถูกต้องในรายการนั้นทำได้ยาก
Contango

1

บางทีโดยIP ภายนอกคุณสามารถพิจารณา (ถ้าคุณอยู่ในบริบทของเว็บเซิร์ฟเวอร์) โดยใช้สิ่งนี้

Request.ServerVariables["LOCAL_ADDR"];

ฉันถามคำถามเดียวกับคุณและฉันพบมันในนี้บทความ StackOverflow

มันใช้งานได้สำหรับฉัน


1
namespace NKUtilities 
{
    using System;
    using System.Net;

    public class DNSUtility
    {
        public static int Main (string [] args)
        {

          String strHostName = new String ("");
          if (args.Length == 0)
          {
              // Getting Ip address of local machine...
              // First get the host name of local machine.
              strHostName = Dns.GetHostName ();
              Console.WriteLine ("Local Machine's Host Name: " +  strHostName);
          }
          else
          {
              strHostName = args[0];
          }

          // Then using host name, get the IP address list..
          IPHostEntry ipEntry = DNS.GetHostByName (strHostName);
          IPAddress [] addr = ipEntry.AddressList;

          for (int i = 0; i < addr.Length; i++)
          {
              Console.WriteLine ("IP Address {0}: {1} ", i, addr[i].ToString ());
          }
          return 0;
        }    
     }
}

1
using System;
using System.Net;

namespace IPADDRESS
{
    class Program
    {
        static void Main(string[] args)
        {
            String strHostName = string.Empty;
            if (args.Length == 0)
            {                
                /* First get the host name of local machine.*/
                strHostName = Dns.GetHostName();
                Console.WriteLine("Local Machine's Host Name: " + strHostName);
            }
            else
            {
                strHostName = args[0];
            }
            /* Then using host name, get the IP address list..*/
            IPHostEntry ipEntry = Dns.GetHostByName(strHostName);
            IPAddress[] addr = ipEntry.AddressList;
            for (int i = 0; i < addr.Length; i++)
            {
                Console.WriteLine("IP Address {0}: {1} ", i, addr[i].ToString());
            }
            Console.ReadLine();
        }
    }
}

1
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);

Simple บรรทัดเดียวของรหัสที่ส่งกลับที่อยู่ IPV4 ภายในครั้งแรกหรือเป็นโมฆะหากไม่มี เพิ่มเป็นความคิดเห็นด้านบน แต่อาจเป็นประโยชน์กับใครบางคน (โซลูชันบางตัวด้านบนจะส่งคืนที่อยู่หลายรายการที่ต้องมีการกรองเพิ่มเติม)

นอกจากนี้ยังง่ายต่อการส่งคืนลูปแบ็คแทนที่จะเป็นโมฆะฉันเดาด้วย:

return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork) ?? new IPAddress( new byte[] {127, 0, 0, 1} );

1
แล้วไงIPAddress.Loopbackล่ะ :)
CodeTherapist

1

เพื่อค้นหารายการที่อยู่ IP ฉันใช้วิธีนี้

public static IEnumerable<string> GetAddresses()
{
    var host = Dns.GetHostEntry(Dns.GetHostName());
    return (from ip in host.AddressList where ip.AddressFamily == AddressFamily.lo select ip.ToString()).ToList();
}

แต่ส่วนตัวฉันชอบวิธีการแก้ปัญหาด้านล่างเพื่อรับที่อยู่ IP ท้องถิ่นที่ถูกต้อง

public static IPAddress GetIPAddress(string hostName)
{
    Ping ping = new Ping();
    var replay = ping.Send(hostName);

    if (replay.Status == IPStatus.Success)
    {
        return replay.Address;
    }
    return null;
 }

public static void Main()
{
    Console.WriteLine("Local IP Address: " + GetIPAddress(Dns.GetHostName()));
    Console.WriteLine("Google IP:" + GetIPAddress("google.com");
    Console.ReadLine();
}


1

นี่คือวิธีที่ฉันแก้ไขมัน ฉันรู้ว่าถ้าคุณมีอินเทอร์เฟซทางกายภาพหลายตัวนี่อาจไม่ได้เลือก eth ที่แน่นอนที่คุณต้องการ

private string FetchIP()
{
    //Get all IP registered
    List<string> IPList = new List<string>();
    IPHostEntry host;
    host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (IPAddress ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            IPList.Add(ip.ToString());
        }
    }

    //Find the first IP which is not only local
    foreach (string a in IPList)
    {
        Ping p = new Ping();
        string[] b = a.Split('.');
        string ip2 = b[0] + "." + b[1] + "." + b[2] + ".1";
        PingReply t = p.Send(ip2);
        p.Dispose();
        if (t.Status == IPStatus.Success && ip2 != a)
        {
            return a;
        }
    }
    return null;
}


1

รับที่อยู่ IP ทั้งหมดเป็นสตริงโดยใช้ LINQ:

using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
...
string[] allIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
    .SelectMany(c=>c.GetIPProperties().UnicastAddresses
        .Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork)
        .Select(d=>d.Address.ToString())
    ).ToArray();

เพื่อกรองความเป็นส่วนตัวออกไป ...

ก่อนกำหนดวิธีการขยายIsPrivate():

public static class IPAddressExtensions
{
    // Collection of private CIDRs (IpAddress/Mask) 
    private static Tuple<int, int>[] _privateCidrs = new []{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}
        .Select(c=>Tuple.Create(BitConverter.ToInt32(IPAddress
                                    .Parse(c.Split('/')[0]).GetAddressBytes(), 0)
                              , IPAddress.HostToNetworkOrder(-1 << (32-int.Parse(c.Split('/')[1])))))
        .ToArray();
    public static bool IsPrivate(this IPAddress ipAddress)
    {
        int ip = BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0);
        return _privateCidrs.Any(cidr=>(ip & cidr.Item2)==(cidr.Item1 & cidr.Item2));           
    }
}

... จากนั้นใช้เพื่อกรอง IP ส่วนตัว:

string[] publicIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
    .SelectMany(c=>c.GetIPProperties().UnicastAddresses
        .Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork
            && !d.Address.IsPrivate() // Filter out private ones
        )
        .Select(d=>d.Address.ToString())
    ).ToArray();

1

มันทำงานได้สำหรับฉัน ... และควรจะเร็วกว่าในกรณีส่วนใหญ่ (ถ้าไม่ใช่ทั้งหมด) กว่าการสอบถามเซิร์ฟเวอร์ DNS ขอบคุณ Apprentice ของ Dr. Wily ( ที่นี่ )

// ************************************************************************
/// <summary>
/// Will search for the an active NetworkInterafce that has a Gateway, otherwise
/// it will fallback to try from the DNS which is not safe.
/// </summary>
/// <returns></returns>
public static NetworkInterface GetMainNetworkInterface()
{
    List<NetworkInterface> candidates = new List<NetworkInterface>();

    if (NetworkInterface.GetIsNetworkAvailable())
    {
        NetworkInterface[] NetworkInterfaces =
            NetworkInterface.GetAllNetworkInterfaces();

        foreach (
            NetworkInterface ni in NetworkInterfaces)
        {
            if (ni.OperationalStatus == OperationalStatus.Up)
                candidates.Add(ni);
        }
    }

    if (candidates.Count == 1)
    {
        return candidates[0];
    }

    // Accoring to our tech, the main NetworkInterface should have a Gateway 
    // and it should be the ony one with a gateway.
    if (candidates.Count > 1)
    {
        for (int n = candidates.Count - 1; n >= 0; n--)
        {
            if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
            {
                candidates.RemoveAt(n);
            }
        }

        if (candidates.Count == 1)
        {
            return candidates[0];
        }
    }

    // Fallback to try by getting my ipAdress from the dns
    IPAddress myMainIpAdress = null;
    IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (IPAddress ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
        {
            myMainIpAdress = ip;
            break;
        }
    }

    if (myMainIpAdress != null)
    {
        NetworkInterface[] NetworkInterfaces =
            NetworkInterface.GetAllNetworkInterfaces();

        foreach (NetworkInterface ni in NetworkInterfaces)
        {
            if (ni.OperationalStatus == OperationalStatus.Up)
            {
                IPInterfaceProperties props = ni.GetIPProperties();
                foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                {
                    if (ai.Address.Equals(myMainIpAdress))
                    {
                        return ni;
                    }
                }
            }
        }
    }

    return null;
}

// ******************************************************************
/// <summary>
/// AddressFamily.InterNetwork = IPv4
/// Thanks to Dr. Wilys Apprentice at
/// http://stackoverflow.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
/// using System.Net.NetworkInformation;
/// </summary>
/// <param name="mac"></param>
/// <param name="addressFamily">AddressFamily.InterNetwork = IPv4,  AddressFamily.InterNetworkV6 = IPv6</param>
/// <returns></returns>
public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
    NetworkInterface[] NetworkInterfaces =
        NetworkInterface.GetAllNetworkInterfaces();

    foreach (NetworkInterface ni in NetworkInterfaces)
    {
        if (ni.GetPhysicalAddress().Equals(mac))
        {
            if (ni.OperationalStatus == OperationalStatus.Up)
            {
                IPInterfaceProperties props = ni.GetIPProperties();
                foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                {
                    if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
                    {
                        if (ai.Address.AddressFamily == addressFamily)
                        {
                            return ai.Address;
                        }
                    }
                }
            }
        }
    }

    return null;
}

// ******************************************************************
/// <summary>
/// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call 
/// '?.ToString() ?? ""' on the result.
/// </summary>
/// <returns></returns>
public static IPAddress GetMyInternetIpAddress()
{
    NetworkInterface ni = GetMainNetworkInterface();
    IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
    if (ipAddress == null) // could it be possible ?
    {
        ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
    }

    return ipAddress;
}

// ******************************************************************

เช่นเดียวกับการอ้างอิงนี่คือรหัสคลาสเต็มรูปแบบที่ฉันกำหนดไว้:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace TcpMonitor
{
    /*
        Usage:
                var cons = TcpHelper.GetAllTCPConnections();
                foreach (TcpHelper.MIB_TCPROW_OWNER_PID c in cons) ...
    */

    public class NetHelper
    {
        [DllImport("iphlpapi.dll", SetLastError = true)]
        static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int dwOutBufLen, bool sort, int ipVersion, UDP_TABLE_CLASS tblClass, uint reserved = 0);

        public enum UDP_TABLE_CLASS
        {
            UDP_TABLE_BASIC,
            UDP_TABLE_OWNER_PID,
            UDP_TABLE_OWNER_MODULE
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDPTABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_UDPROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDPROW_OWNER_PID
        {
            public uint localAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            public uint owningPid;

            public uint ProcessId
            {
                get { return owningPid; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr); }
            }

            public ushort LocalPort
            {
                get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDP6TABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_UDP6ROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDP6ROW_OWNER_PID
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] localAddr;
            public uint localScopeId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            public uint owningPid;
            public uint ProcessId
            {
                get { return owningPid; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr, localScopeId); }
            }

            public ushort LocalPort
            {
                get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
            }
        }

        public static List<MIB_UDPROW_OWNER_PID> GetAllUDPConnections()
        {
            return GetUDPConnections<MIB_UDPROW_OWNER_PID, MIB_UDPTABLE_OWNER_PID> (AF_INET);
        }

        public static List<MIB_UDP6ROW_OWNER_PID> GetAllUDPv6Connections()
        {
            return GetUDPConnections<MIB_UDP6ROW_OWNER_PID, MIB_UDP6TABLE_OWNER_PID>(AF_INET6);
        }

        private static List<IPR> GetUDPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
        {
            List<IPR> result = null;

            IPR[] tableRows = null;
            int buffSize = 0;

            var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");

            // how much memory do we need?
            uint ret = GetExtendedUdpTable(IntPtr.Zero, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
            IntPtr udpTablePtr = Marshal.AllocHGlobal(buffSize);

            try
            {
                ret = GetExtendedUdpTable(udpTablePtr, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
                if (ret != 0)
                    return new List<IPR>();

                // get the number of entries in the table
                IPT table = (IPT)Marshal.PtrToStructure(udpTablePtr, typeof(IPT));
                int rowStructSize = Marshal.SizeOf(typeof(IPR));
                uint numEntries = (uint)dwNumEntriesField.GetValue(table);

                // buffer we will be returning
                tableRows = new IPR[numEntries];

                IntPtr rowPtr = (IntPtr)((long)udpTablePtr + 4);
                for (int i = 0; i < numEntries; i++)
                {
                    IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
                    tableRows[i] = tcpRow;
                    rowPtr = (IntPtr)((long)rowPtr + rowStructSize);   // next entry
                }
            }
            finally
            {
                result = tableRows?.ToList() ?? new List<IPR>();

                // Free the Memory
                Marshal.FreeHGlobal(udpTablePtr);
            }

            return result;
        }

        [DllImport("iphlpapi.dll", SetLastError = true)]
        static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, uint reserved = 0);



        public enum MIB_TCP_STATE
        {
            MIB_TCP_STATE_CLOSED = 1,
            MIB_TCP_STATE_LISTEN = 2,
            MIB_TCP_STATE_SYN_SENT = 3,
            MIB_TCP_STATE_SYN_RCVD = 4,
            MIB_TCP_STATE_ESTAB = 5,
            MIB_TCP_STATE_FIN_WAIT1 = 6,
            MIB_TCP_STATE_FIN_WAIT2 = 7,
            MIB_TCP_STATE_CLOSE_WAIT = 8,
            MIB_TCP_STATE_CLOSING = 9,
            MIB_TCP_STATE_LAST_ACK = 10,
            MIB_TCP_STATE_TIME_WAIT = 11,
            MIB_TCP_STATE_DELETE_TCB = 12
        }

        public enum TCP_TABLE_CLASS
        {
            TCP_TABLE_BASIC_LISTENER,
            TCP_TABLE_BASIC_CONNECTIONS,
            TCP_TABLE_BASIC_ALL,
            TCP_TABLE_OWNER_PID_LISTENER,
            TCP_TABLE_OWNER_PID_CONNECTIONS,
            TCP_TABLE_OWNER_PID_ALL,
            TCP_TABLE_OWNER_MODULE_LISTENER,
            TCP_TABLE_OWNER_MODULE_CONNECTIONS,
            TCP_TABLE_OWNER_MODULE_ALL
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPTABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_TCPROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCP6TABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_TCP6ROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPROW_OWNER_PID
        {
            public uint state;
            public uint localAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            public uint remoteAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] remotePort;
            public uint owningPid;

            public uint ProcessId
            {
                get { return owningPid; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr); }
            }

            public ushort LocalPort
            {
                get
                {
                    return BitConverter.ToUInt16(new byte[2] { localPort[1], localPort[0] }, 0);
                }
            }

            public IPAddress RemoteAddress
            {
                get { return new IPAddress(remoteAddr); }
            }

            public ushort RemotePort
            {
                get
                {
                    return BitConverter.ToUInt16(new byte[2] { remotePort[1], remotePort[0] }, 0);
                }
            }

            public MIB_TCP_STATE State
            {
                get { return (MIB_TCP_STATE)state; }
            }
        }


        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCP6ROW_OWNER_PID
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] localAddr;
            public uint localScopeId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] remoteAddr;
            public uint remoteScopeId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] remotePort;
            public uint state;
            public uint owningPid;

            public uint ProcessId
            {
                get { return owningPid; }
            }

            public long LocalScopeId
            {
                get { return localScopeId; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr, LocalScopeId); }
            }

            public ushort LocalPort
            {
                get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
            }

            public long RemoteScopeId
            {
                get { return remoteScopeId; }
            }

            public IPAddress RemoteAddress
            {
                get { return new IPAddress(remoteAddr, RemoteScopeId); }
            }

            public ushort RemotePort
            {
                get { return BitConverter.ToUInt16(remotePort.Take(2).Reverse().ToArray(), 0); }
            }

            public MIB_TCP_STATE State
            {
                get { return (MIB_TCP_STATE)state; }
            }
        }


        public const int AF_INET = 2;    // IP_v4 = System.Net.Sockets.AddressFamily.InterNetwork
        public const int AF_INET6 = 23;  // IP_v6 = System.Net.Sockets.AddressFamily.InterNetworkV6

        public static Task<List<MIB_TCPROW_OWNER_PID>> GetAllTCPConnectionsAsync()
        {
            return Task.Run(() => GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET));
        }

        public static List<MIB_TCPROW_OWNER_PID> GetAllTCPConnections()
        {
            return GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET);
        }

        public static Task<List<MIB_TCP6ROW_OWNER_PID>> GetAllTCPv6ConnectionsAsync()
        {
            return Task.Run(()=>GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6));
        }

        public static List<MIB_TCP6ROW_OWNER_PID> GetAllTCPv6Connections()
        {
            return GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6);
        }

        private static List<IPR> GetTCPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
        {
            List<IPR> result = null;

            IPR[] tableRows = null;
            int buffSize = 0;

            var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");

            // how much memory do we need?
            uint ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
            IntPtr tcpTablePtr = Marshal.AllocHGlobal(buffSize);

            try
            {
                ret = GetExtendedTcpTable(tcpTablePtr, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
                if (ret != 0)
                    return new List<IPR>();

                // get the number of entries in the table
                IPT table = (IPT)Marshal.PtrToStructure(tcpTablePtr, typeof(IPT));
                int rowStructSize = Marshal.SizeOf(typeof(IPR));
                uint numEntries = (uint)dwNumEntriesField.GetValue(table);

                // buffer we will be returning
                tableRows = new IPR[numEntries];

                IntPtr rowPtr = (IntPtr)((long)tcpTablePtr + 4);
                for (int i = 0; i < numEntries; i++)
                {
                    IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
                    tableRows[i] = tcpRow;
                    rowPtr = (IntPtr)((long)rowPtr + rowStructSize);   // next entry
                }
            }
            finally
            {
                result = tableRows?.ToList() ?? new List<IPR>();

                // Free the Memory
                Marshal.FreeHGlobal(tcpTablePtr);
            }

            return result;
        }

        public static string GetTcpStateName(MIB_TCP_STATE state)
        {
            switch (state)
            {
                case MIB_TCP_STATE.MIB_TCP_STATE_CLOSED:
                    return "Closed";
                case MIB_TCP_STATE.MIB_TCP_STATE_LISTEN:
                    return "Listen";
                case MIB_TCP_STATE.MIB_TCP_STATE_SYN_SENT:
                    return "SynSent";
                case MIB_TCP_STATE.MIB_TCP_STATE_SYN_RCVD:
                    return "SynReceived";
                case MIB_TCP_STATE.MIB_TCP_STATE_ESTAB:
                    return "Established";
                case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT1:
                    return "FinWait 1";
                case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT2:
                    return "FinWait 2";
                case MIB_TCP_STATE.MIB_TCP_STATE_CLOSE_WAIT:
                    return "CloseWait";
                case MIB_TCP_STATE.MIB_TCP_STATE_CLOSING:
                    return "Closing";
                case MIB_TCP_STATE.MIB_TCP_STATE_LAST_ACK:
                    return "LastAck";
                case MIB_TCP_STATE.MIB_TCP_STATE_TIME_WAIT:
                    return "TimeWait";
                case MIB_TCP_STATE.MIB_TCP_STATE_DELETE_TCB:
                    return "DeleteTCB";
                default:
                    return ((int)state).ToString();
            }
        }

        private static readonly ConcurrentDictionary<string, string> DicOfIpToHostName = new ConcurrentDictionary<string, string>();

        public const string UnknownHostName = "Unknown";

        // ******************************************************************
        public static string GetHostName(IPAddress ipAddress)
        {
            return GetHostName(ipAddress.ToString());
        }

        // ******************************************************************
        public static string GetHostName(string ipAddress)
        {
            string hostName = null;

            if (!DicOfIpToHostName.TryGetValue(ipAddress, out hostName))
            {
                try
                {
                    if (ipAddress == "0.0.0.0" || ipAddress == "::")
                    {
                        hostName = ipAddress;
                    }
                    else
                    {
                        hostName = Dns.GetHostEntry(ipAddress).HostName;
                    }
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.ToString());
                    hostName = UnknownHostName;
                }

                DicOfIpToHostName[ipAddress] = hostName;
            }

            return hostName;
        }

        // ************************************************************************
        /// <summary>
        /// Will search for the an active NetworkInterafce that has a Gateway, otherwise
        /// it will fallback to try from the DNS which is not safe.
        /// </summary>
        /// <returns></returns>
        public static NetworkInterface GetMainNetworkInterface()
        {
            List<NetworkInterface> candidates = new List<NetworkInterface>();

            if (NetworkInterface.GetIsNetworkAvailable())
            {
                NetworkInterface[] NetworkInterfaces =
                    NetworkInterface.GetAllNetworkInterfaces();

                foreach (
                    NetworkInterface ni in NetworkInterfaces)
                {
                    if (ni.OperationalStatus == OperationalStatus.Up)
                        candidates.Add(ni);
                }
            }

            if (candidates.Count == 1)
            {
                return candidates[0];
            }

            // Accoring to our tech, the main NetworkInterface should have a Gateway 
            // and it should be the ony one with a gateway.
            if (candidates.Count > 1)
            {
                for (int n = candidates.Count - 1; n >= 0; n--)
                {
                    if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
                    {
                        candidates.RemoveAt(n);
                    }
                }

                if (candidates.Count == 1)
                {
                    return candidates[0];
                }
            }

            // Fallback to try by getting my ipAdress from the dns
            IPAddress myMainIpAdress = null;
            IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
                {
                    myMainIpAdress = ip;
                    break;
                }
            }

            if (myMainIpAdress != null)
            {
                NetworkInterface[] NetworkInterfaces =
                    NetworkInterface.GetAllNetworkInterfaces();

                foreach (NetworkInterface ni in NetworkInterfaces)
                {
                    if (ni.OperationalStatus == OperationalStatus.Up)
                    {
                        IPInterfaceProperties props = ni.GetIPProperties();
                        foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                        {
                            if (ai.Address.Equals(myMainIpAdress))
                            {
                                return ni;
                            }
                        }
                    }
                }
            }

            return null;
        }

        // ******************************************************************
        /// <summary>
        /// AddressFamily.InterNetwork = IPv4
        /// Thanks to Dr. Wilys Apprentice at
        /// http://stackoverflow.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
        /// using System.Net.NetworkInformation;
        /// </summary>
        /// <param name="mac"></param>
        /// <param name="addressFamily">AddressFamily.InterNetwork = IPv4,  AddressFamily.InterNetworkV6 = IPv6</param>
        /// <returns></returns>
        public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
        {
            NetworkInterface[] NetworkInterfaces =
                NetworkInterface.GetAllNetworkInterfaces();

            foreach (NetworkInterface ni in NetworkInterfaces)
            {
                if (ni.GetPhysicalAddress().Equals(mac))
                {
                    if (ni.OperationalStatus == OperationalStatus.Up)
                    {
                        IPInterfaceProperties props = ni.GetIPProperties();
                        foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                        {
                            if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
                            {
                                if (ai.Address.AddressFamily == addressFamily)
                                {
                                    return ai.Address;
                                }
                            }
                        }
                    }
                }
            }

            return null;
        }

        // ******************************************************************
        /// <summary>
        /// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call 
        /// '?.ToString() ?? ""' on the result.
        /// </summary>
        /// <returns></returns>
        public static IPAddress GetMyInternetIpAddress()
        {
            NetworkInterface ni = GetMainNetworkInterface();
            IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
            if (ipAddress == null) // could it be possible ?
            {
                ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
            }

            return ipAddress;
        }

        // ******************************************************************
        public static bool IsBroadcastAddress(IPAddress ipAddress)
        {
            if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                return ipAddress.GetAddressBytes()[3] == 255;
            }

            if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
            {
                return false; // NO broadcast in IPv6
            }

            return false;
        }

        // ******************************************************************
        public static bool IsMulticastAddress(IPAddress ipAddress)
        {
            if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                // Source: https://technet.microsoft.com/en-us/library/cc772041(v=ws.10).aspx
                return ipAddress.GetAddressBytes()[0] >= 224 && ipAddress.GetAddressBytes()[0] <= 239;
            }

            if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
            {
                return ipAddress.IsIPv6Multicast;
            }

            return false;
        }

        // ******************************************************************

    }
}

1

อีกวิธีหนึ่งในการรับที่อยู่ IP สาธารณะของคุณคือการใช้resolve1.opendns.comเซิร์ฟเวอร์ของ OpenDNS พร้อมกับmyip.opendns.comคำขอ

ในบรรทัดคำสั่งนี่คือ:

  nslookup myip.opendns.com resolver1.opendns.com

หรือใน C # โดยใช้ DNSClient nuget:

  var lookup = new LookupClient(new IPAddress(new byte[] { 208, 67, 222, 222 }));
  var result = lookup.Query("myip.opendns.com", QueryType.ANY);

สิ่งนี้ค่อนข้างสะอาดกว่าการกดจุดปลาย http และการแยกวิเคราะห์คำตอบ


0

และนี่คือการรับ IP ท้องถิ่นทั้งหมดในรูปแบบ csv ใน VB.NET

Imports System.Net
Imports System.Net.Sockets

Function GetIPAddress() As String
    Dim ipList As List(Of String) = New List(Of String)
    Dim host As IPHostEntry
    Dim localIP As String = "?"
    host = Dns.GetHostEntry(Dns.GetHostName())
    For Each ip As IPAddress In host.AddressList
        If ip.AddressFamily = AddressFamily.InterNetwork Then
            localIP = ip.ToString()
            ipList.Add(localIP)
        End If
    Next
    Dim ret As String = String.Join(",", ipList.ToArray)
    Return ret
End Function

0

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

ข้อเสียในการใช้รหัสง่าย ๆ นี้: (ซึ่งแนะนำให้ใช้) คือการที่จะใช้เวลา 3-5 วินาทีในการรับที่อยู่ IP ระยะไกลของคุณเนื่องจาก WebClient เมื่อเริ่มต้นจะใช้เวลา 3-5 วินาทีในการตรวจสอบการตั้งค่าพร็อกซีของคุณเสมอ

 public static string GetIP()
 {
            string externalIP = "";
            externalIP = new WebClient().DownloadString("http://checkip.dyndns.org/");
            externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                                           .Matches(externalIP)[0].ToString();
            return externalIP;
 }

นี่คือวิธีที่ฉันแก้ไขมัน .. (ครั้งแรกยังคงใช้เวลา 3-5 วินาที) แต่หลังจากนั้นมันจะได้รับที่อยู่ IP ระยะไกลของคุณใน 0-2 วินาทีขึ้นอยู่กับการเชื่อมต่อของคุณ

public static WebClient webclient = new WebClient();
public static string GetIP()
{
    string externalIP = "";
    externalIP = webclient.DownloadString("http://checkip.dyndns.org/");
    externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                                   .Matches(externalIP)[0].ToString();
    return externalIP;
}

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