【问题标题】:Cannot find IP from Hostname无法从主机名中找到 IP
【发布时间】:2015-05-18 11:53:48
【问题描述】:

我有一个运行网络服务器的 wifi 传感器模块 (SN8200 EVK)。 该板被配置为作为 STA 工作并自动加入 WiFi 路由器。 传感器板使用主机名:“传感器”和 DHCP 接口来获取其 IP 地址。

我正在开发一个 Visual Studio C# 应用程序来连接到这个网络服务器。 该应用程序在连接到同一个 WiFi 路由器的笔记本电脑上运行。

传感器板 WiFi 路由器 笔记本电脑

如果我使用板 IP 地址,应用程序可以连接到传感器板。 由于 IP 地址不是静态的,我想使用主机名来检索 IP。

我尝试使用 GetHostEntry,但得到未知主机结果。

IPHostEntry host;
host = Dns.GetHostEntry("sensor");

奇怪的是,如果我将 GetHostEntry 与 IP 地址一起使用,它也无法解析主机名。

如果我尝试使用笔记本电脑主机名或 IP,GetHostEntry 工作正常。 看起来 GetHostEntry 无法解析路由器后面的主机名。

欢迎任何帮助, 谢谢。

【问题讨论】:

  • 如果不在DNS或hosts文件中,则无法通过名称解析。而且标题有点误导
  • 这主要取决于传感器板是尝试在 DNS 服务器中注册自己还是必须手动完成。一个简单的测试,试试ping sensor 看看你的电脑是否知道这个主机名。如果没有,请尝试将传感器添加到您的 DNS 服务器或主机文件中。
  • WiFi 路由器能否与动态(变化的)IP 地址保持名称关联?
  • 为什么不是蒂姆?如果每个更改都已注册,我不明白为什么它不会维护 DNS。
  • @Tim 可以吗?绝对地。可以?这取决于路由器型号。

标签: c# .net hostname


【解决方案1】:

静态IP解决方案

第一:

在您的 Wifi 路由器中配置 DHCP 服务器内的固定 IP 地址。
PS:我很确定 Mac 地址不是动态的

第二:

使用之前固定的 IP 地址在 DNS 服务器中添加主机名。

扫描网络的 IP 并检查 Mac 地址解决方案

在使用以下代码之前,您必须 ping 传感器板可以使用的整个 IP 范围以刷新您的 ARP 缓存。

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Net;
using System.Collections.Generic;

namespace GetIpNetTable
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] ips = searchIpsFromMac("ff-ff-ff-ff-ff-ff");
            if (ips.Length != 0)
            {
                foreach (string ip in ips)
                {
                    // TODO - Do what you want with your IP address
                    Console.WriteLine(ip);
                }
            }
            Console.ReadKey();
        }

        // The max number of physical addresses.
        const int MAXLEN_PHYSADDR = 8;

        // Define the MIB_IPNETROW structure.
        [StructLayout(LayoutKind.Sequential)]
        struct MIB_IPNETROW
        {
            [MarshalAs(UnmanagedType.U4)]
            public int dwIndex;
            [MarshalAs(UnmanagedType.U4)]
            public int dwPhysAddrLen;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac0;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac1;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac2;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac3;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac4;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac5;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac6;
            [MarshalAs(UnmanagedType.U1)]
            public byte mac7;
            [MarshalAs(UnmanagedType.U4)]
            public int dwAddr;
            [MarshalAs(UnmanagedType.U4)]
            public int dwType;
        }

        // Declare the GetIpNetTable function.
        [DllImport("IpHlpApi.dll")]
        [return: MarshalAs(UnmanagedType.U4)]
        static extern int GetIpNetTable(
           IntPtr pIpNetTable,
           [MarshalAs(UnmanagedType.U4)]
         ref int pdwSize,
           bool bOrder);

        [DllImport("IpHlpApi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        internal static extern int FreeMibTable(IntPtr plpNetTable);

        // The insufficient buffer error.
        const int ERROR_INSUFFICIENT_BUFFER = 122;

        static string[] searchIpsFromMac(string macSearched)
        {
            List<string> ips = new List<string>(1);

            // The number of bytes needed.
            int bytesNeeded = 0;

            // The result from the API call.
            int result = GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false);

            // Call the function, expecting an insufficient buffer.
            if (result != ERROR_INSUFFICIENT_BUFFER)
            {
                // Throw an exception.
                throw new Win32Exception(result);
            }

            // Allocate the memory, do it in a try/finally block, to ensure
            // that it is released.
            IntPtr buffer = IntPtr.Zero;

            // Try/finally.
            try
            {
                // Allocate the memory.
                buffer = Marshal.AllocCoTaskMem(bytesNeeded);

                // Make the call again. If it did not succeed, then
                // raise an error.
                result = GetIpNetTable(buffer, ref bytesNeeded, false);

                // If the result is not 0 (no error), then throw an exception.
                if (result != 0)
                {
                    // Throw an exception.
                    throw new Win32Exception(result);
                }

                // Now we have the buffer, we have to marshal it. We can read
                // the first 4 bytes to get the length of the buffer.
                int entries = Marshal.ReadInt32(buffer);

                // Increment the memory pointer by the size of the int.
                IntPtr currentBuffer = new IntPtr(buffer.ToInt64() +
                   Marshal.SizeOf(typeof(int)));

                // Allocate an array of entries.
                MIB_IPNETROW[] table = new MIB_IPNETROW[entries];

                // Cycle through the entries.
                for (int index = 0; index < entries; index++)
                {
                    // Call PtrToStructure, getting the structure information.
                    table[index] = (MIB_IPNETROW)Marshal.PtrToStructure(new
                       IntPtr(currentBuffer.ToInt64() + (index *
                       Marshal.SizeOf(typeof(MIB_IPNETROW)))), typeof(MIB_IPNETROW));
                }

                for (int index = 0; index < entries; index++)
                {
                    MIB_IPNETROW row = table[index];
                    IPAddress ip = new IPAddress(BitConverter.GetBytes(row.dwAddr));
                    string macAddr = row.mac0.ToString("X2") + '-' +
                        row.mac1.ToString("X2") + '-' +
                        row.mac2.ToString("X2") + '-' +
                        row.mac3.ToString("X2") + '-' +
                        row.mac4.ToString("X2") + '-' +
                        row.mac5.ToString("X2");
                    if (macAddr.ToUpper() == macSearched.ToUpper())
                    {
                        ips.Add(ip.ToString());
                    }
                }
            }
            finally
            {
                // Release the memory.
                FreeMibTable(buffer);
            }
            return ips.ToArray();
        }
    }
}

参考: https://stackoverflow.com/a/1148861/3635715

【讨论】:

  • 是的,如果我修复了 IP 地址,我在找到传感器板时不会有任何问题。我什至不需要主机名来访问董事会。我想避免固定 IP 地址以使客户更容易,因为我不会在那里设置他们的网络。我对如何保持 IP 地址动态并在网络上找到这个传感器板有点迷茫。有没有办法扫描一系列 IP 地址以查找网络上的设备(使用主机名或其他)?抱歉,我不太了解网络...
  • DNS 服务器使用 IP 固定名称。如果 IP 发生变化,DNS 将不会指向任何内容。由于您的传感器板不与 DNS 服务器通信。它不会通知 IP 已更改,也不会将新的主机名/IP 注册到 DNS 服务器。因此,在每次 IP 更改时,如果不手动更改 DNS 注册表,您就无法使用 DNS 实现动态 IP 行为。这就是为什么您需要修复 IP(或者有一些东西定期扫描网络以检查此传感器板的新 IP)。
猜你喜欢
  • 2012-05-12
  • 2014-02-15
  • 1970-01-01
  • 2011-12-29
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 2011-02-04
相关资源
最近更新 更多