筆記-使用 Dns.GetHostEntry 解析 IP 位址

某排程使用以下程式碼產生 IEndPoint 以建立 Socket:

IPEndPoint pEndPoint = new IPEndPoint(Dns.GetHostEntry(remoteHost).AddressList[0], remotePort);

其中用了 Dns.GetHostEntry(),好處是不管 remoteHost 傳入的是主機名稱還是 IP,一律可轉成 IPAddress。

排程在正式及測試環境運作多時,今天將程式移到另一網段機器上執行,remoteHost 為 IP 位址(假設為 192.168.1.1),與原本設定相同,確認新主機與 192.168.1.1 間網路暢通,甚至用 telnet 192.168.1.1 portNo 建立連線也成功,但程式一執行就出現以下錯誤:

[SocketException (0x2af9): No such host is known]
   System.Net.Dns.InternalGetHostByAddress(IPAddress address, Boolean includeIPv6) +2221072
   System.Net.Dns.GetHostEntry(String hostNameOrAddress) +6671028

認真看了 MSDN 文件,搞懂 GetHostEntry() 邏輯才恍然大悟。

GetHostEntry 的介面為:

public static IPHostEntry GetHostEntry(
    string hostNameOrAddress
)

其中 hostNameOrAddress 參數可以是主機名稱也可以是 IP 位址。當傳入 IP 時 GetHostEntry 假設程式想取得 IPHostEntry 的完整資訊-包含 AddressList, Aliases, 與 HostName,因此將執行以下動作:

  1. 嘗試解析 IP 位址,若 hostNameOrAddress 傳入的是有效 IP 位址字串,轉成 IP 位址物件不是問題
  2. 利用 IP 反查取得主機名稱存入 HostName
  3. 利用主機名稱查詢該主機的所有 IP 位址,存入 AddressList

今天出錯的關鍵在於程式原本所在的正式與測試主機與 192.168.1.1 隸屬同一網域,而問題主機則屬於另一個網域,兩個網域雖有信任關係,但 WINS 及 DNS 反查未打通,故在進行第 2 步以 IP 反查 HostName 時踏到鐵板,產生 No such host is known 錯誤。

知道原因就好辦,有幾種解決方法:

  1. 設定 system32/drivers/etc/hosts 讓 192.168.1.1 能反查到主機名稱
  2. 改用 FQDN,GetHostEntry() 改成用 FQDN 解析 IP(DNS 解析的功能是好的)
  3. 修改程式,當 remoteHost 為 IP 位址時不走 GetHostEntry(),改用 IPAddress.Parse()

最後採行方案 2,問題排除。

歡迎推文分享:
Published 21 June 2017 10:30 PM 由 Jeffrey
Filed under: ,
Views: 2,811



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<June 2017>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication