最近,在研究程序时,我发现.net(或至少在ping类中)的主机名不应超过126个字符。如果主机名较长,则ping类将引发异常。
但是,维基百科指出最多允许255个字符。
而且看起来确实存在主机名超过126个字符的机器,所以问题是:可以更改此限制,谁是正确的,如果不能更改名称,该如何解析?
最佳答案
.NET Dns
类的主机名硬上限为126个字符(已检查.NET4)。
但是,可以通过P/Invoke使用较低级别的Win32 DnsQuery
方法将主机名转换为IP地址,然后将这些原始地址与.NET网络类一起使用。
这是使用此方法的示例DnsAddr
类:
public static class DnsAddr
{
[DllImport("dnsapi", EntryPoint = "DnsQuery_W", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
private static extern int DnsQuery([MarshalAs(UnmanagedType.VBByRefStr)]ref string pszName, QueryTypes wType, QueryOptions options, int aipServers, ref IntPtr ppQueryResults, int pReserved);
[DllImport("dnsapi", CharSet = CharSet.Auto, SetLastError = true)]
private static extern void DnsRecordListFree(IntPtr pRecordList, int FreeType);
public static IEnumerable<IPAddress> GetAddress(string domain)
{
IntPtr ptr1 = IntPtr.Zero;
IntPtr ptr2 = IntPtr.Zero;
List<IPAddress> list = new List<IPAddress>();
DnsRecord record = new DnsRecord();
int num1 = DnsAddr.DnsQuery(ref domain, QueryTypes.DNS_TYPE_A, QueryOptions.DNS_QUERY_NONE, 0, ref ptr1, 0);
if (num1 != 0)
throw new Win32Exception(num1);
for (ptr2 = ptr1; !ptr2.Equals(IntPtr.Zero); ptr2 = record.pNext)
{
record = (DnsRecord)Marshal.PtrToStructure(ptr2, typeof(DnsRecord));
list.Add(new IPAddress(record.ipAddress));
}
DnsAddr.DnsRecordListFree(ptr1, 0);
return list;
}
private enum QueryOptions
{
DNS_QUERY_NONE = 0,
}
private enum QueryTypes
{
DNS_TYPE_A = 1,
}
[StructLayout(LayoutKind.Sequential)]
private struct DnsRecord
{
public IntPtr pNext;
public string pName;
public short wType;
public short wDataLength;
public int flags;
public int dwTtl;
public int dwReserved;
public uint ipAddress;
}
}
这是一个示例测试程序:
class Program
{
static void Main(string[] args)
{
var addresses = DnsAddr.GetAddress("google.com");
foreach (var address in addresses)
Console.WriteLine(address.ToString());
}
}
我的机器上哪个会产生以下输出:
173.194.33.51
173.194.33.50
173.194.33.49
173.194.33.52
173.194.33.48