2011-10-30 16 views
12

Trong khi làm việc trên một chương trình, gần đây tôi đã tìm thấy tên máy chủ trong .net (hoặc ít nhất trong lớp ping) không được phép có nhiều hơn 126 ký tự. Lớp ping ném một ngoại lệ nếu tên máy chủ dài hơn..NET2 DNS từ chối tên máy chủ trên 126 ký tự là "quá dài"

Tuy nhiên, trạng thái Wikipedia cho phép tối đa 255 ký tự được cho phép. Và có vẻ như thực sự có những máy có tên máy chủ dài hơn 126 ký tự, vì vậy câu hỏi đặt ra là: giới hạn này có thể thay đổi, ai đúng và cách giải quyết tên nếu nó không thể?

+12

Gotta yêu "thông số kỹ thuật". Từ [RFC 1123] (http://www.ietf.org/rfc/rfc1123.txt), "Phần mềm lưu trữ PHẢI xử lý tên máy chủ tối đa 63 ký tự và NÊN xử lý tên máy chủ tối đa 255 ký tự". –

+4

Wikpedia không phải là kho lưu trữ thông số kỹ thuật chính xác. –

+0

@John True. Tuy nhiên có những máy sử dụng nó (ví dụ của tôi là từ google) và nó hoạt động trong dòng lệnh và cũng có trong 3 trình duyệt được cài đặt của tôi. Vì vậy, nó cũng nên làm việc trong .net – FinalNotriX

Trả lời

1

Cả hai thông tin đều đúng.

Giới hạn ký tự 255 đề cập đến toàn bộ tên máy chủ (ví dụ: some.thing.example.com).

Đổi lại, mỗi nhãn (ví dụ: example hoặc com) được giới hạn trong 63 ký tự. Vì vậy, các tên miền cấp cao nhất có giới hạn lý thuyết là 126 ký tự không dấu chấm.

2

Gọi gethostbyname, sau đó vượt qua một địa chỉ IP (đó là không bao giờ nhiều hơn một vài chục nhân vật, ngay cả đối với IPv6) để lớp ping.

9

Lớp .NET Dns có giới hạn trên cứng là 126 ký tự cho tên máy chủ (được chọn cho .NET4).

Tuy nhiên, bạn có thể sử dụng phương thức Win32 DnsQuery cấp thấp hơn bằng cách sử dụng P/Gọi để dịch tên máy chủ thành địa chỉ IP và sau đó sử dụng địa chỉ thô đó với lớp mạng .NET.

Đây là một mẫu DnsAddr lớp sử dụng phương pháp này:

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; 
    } 
} 

Đây là một chương trình thử nghiệm mẫu:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var addresses = DnsAddr.GetAddress("google.com"); 
     foreach (var address in addresses) 
      Console.WriteLine(address.ToString()); 
    } 
} 

đó trên máy tính của tôi sản xuất sản lượng này:

173.194.33.51 
173.194.33.50 
173.194.33.49 
173.194.33.52 
173.194.33.48 
+0

Câu trả lời hay, cảm ơn bạn đã chia sẻ. Lưu ý rằng ví dụ này chỉ tìm kiếm bản ghi DNS_TYPE_A chứ không phải DNS_TYPE_AAAA (0x1c), vì vậy nó sẽ chỉ trả lại địa chỉ IPv4 và không có địa chỉ IPv6. – EricLaw