2014-06-25 34 views
2

我編寫使用套接字的便攜式Windows/Linux應用程序。我使用gethostbyname函數來執行DNS查找。 但是,我不知道如何設置gethostbyname超時,並確保我的應用程序在名稱查找過程中不被掛起。 當然,可以在另一個線程上運行gethostbyname,並且我可以做。但是,它僅適用於微不足道的應用程序。 我的應用程序並行使用1000-3000個連接。在這種情況下,問題是:如何處理超時線程?我沒有看到好的解決方案。我們可以「忘記」它們,但是,我們的程序線程數量會在壞的網絡上增長到無窮大。我們可以終止他們,但這個想法看起來很糟糕。根據我的經驗,在數千個線程終止之後,Windows可能會崩潰,而且我不知道Linux在這種情況下的表現如何。另外,創建線程需要很多資源;創建3000個線程僅用於運行gethostbyname函數並退出並不是一個好主意。 因此,對於真正複雜的應用程序來說,單獨的線程看起來不太好。另一種選擇是編寫自己的DNS客戶端,但是,它也不好看。 有沒有在Windows和Linux(或更好的便攜方式)獲得主機地址與自定義超時的任何「官方」方式?套接字主機名查找超時:如何實現它?

+0

IIRC,一些Windows和Windows Server版本確實通過重疊的I/O機制(GetAddrInfoEx)支持異步查找和超時。但這很難移動。您可以實現一個固定大小的線程池(64?)來運行阻塞查詢和一個由'多個線程'運行的'DNS請求'對象的增量隊列,以實現您的超時。你可以通過POSIX信號量和其他同步對象來實現。 –

+0

您可以使用一些第三方庫來解決或編寫自己的實現。 – someuser

+0

@Martin James GetAddrInfoEx是套接字2,它不是可移植的,甚至更糟糕的是,使用諸如libcurl,openssl之類的套接字1.1來靜態庫編譯togeather是有問題的。可能的便攜式解決方案不存在... – Vitaliy

回答

2

首先的:不要使用gethostbyname(),已經過時了,用getaddrinfo()代替

你想要的是異步名稱解析,這是一個常見的需求,b遺憾的是沒有「標準」的方式,如何去做。在這裏我可以找到適合您的最佳解決方案:

  1. 請勿實施DNS客戶端。名稱解析不僅僅是DNS。想想mDNS,hosts文件等等。使用像getaddrinfo()這樣的系統函數爲您抽象出不同的名稱解析機制。

  2. 某些系統提供分辨率功能的異步版本,如glibc報價getaddrinfo_a()

  3. 還有一些異步解析庫包含了同步系統解析器函數。起初libasyncns出現在我的腦海裏。

  4. Boost.Asio支持將解析器與線程池一起使用。見here

1

最便攜的解決方案的確使用單獨的線程進行名稱解析。這也記錄在MSDN

存在執行異步名稱查找的非便攜式解決方案。

Linux的glibc的2.2.3+:getaddrinfo_a

的Windows:WSAAsyncGetHostByName僅IPv4 :(

有異步DNS庫在那裏:TADNS例如看起來很容易