編輯:關於Android編程
想在 And roid 上使用 libevent 做一個下載程序,牽涉到域名解析的問題,發現 libevent 無法獲取到 dns 服務器。研究了一下源碼,找到了問題所在。
使用 libevent 的異步 dns 解析的一般過程如下:
調用 evdns_base_new(struct event_base *event_base, int initialize_nameservers) 生成一個 evdns_base 對象調用 evdns_getaddrinfo 並提供一個回調進行解析在回調中處理結果一般我們給 evdns_base_new 函數的第二個參數傳遞 1 以便 libevent 從系統配置中初始化 nameservers 。在 windows 上讀取注冊表,在 Linux 上讀取 /etc/resolv.conf 。問題就出在這裡,Android 上沒有 resolv.conf 文件而 libevent 未做處理。查看 evdns.c 文件中的 evdns_base_new 函數實現可知:
struct evdns_base * evdns_base_new(struct event_base *event_base, int initialize_nameservers) { struct evdns_base *base; if (evutil_secure_rng_init() < 0) { log(EVDNS_LOG_WARN, "Unable to seed random number generator; " "DNS can't run."); return NULL; } /* Give the evutil library a hook into its evdns-enabled * functionality. We can't just call evdns_getaddrinfo directly or * else libevent-core will depend on libevent-extras. */ evutil_set_evdns_getaddrinfo_fn(evdns_getaddrinfo); base = mm_malloc(sizeof(struct evdns_base)); if (base == NULL) return (NULL); memset(base, 0, sizeof(struct evdns_base)); base->req_waiting_head = NULL; EVTHREAD_ALLOC_LOCK(base->lock, EVTHREAD_LOCKTYPE_RECURSIVE); EVDNS_LOCK(base); /* Set max requests inflight and allocate req_heads. */ base->req_heads = NULL; evdns_base_set_max_requests_inflight(base, 64); base->server_head = NULL; base->event_base = event_base; base->global_good_nameservers = base->global_requests_inflight = base->global_requests_waiting = 0; base->global_timeout.tv_sec = 5; base->global_timeout.tv_usec = 0; base->global_max_reissues = 1; base->global_max_retransmits = 3; base->global_max_nameserver_timeout = 3; base->global_search_state = NULL; base->global_randomize_case = 1; base->global_getaddrinfo_allow_skew.tv_sec = 3; base->global_getaddrinfo_allow_skew.tv_usec = 0; base->global_nameserver_probe_initial_timeout.tv_sec = 10; base->global_nameserver_probe_initial_timeout.tv_usec = 0; TAILQ_INIT(&base->hostsdb); if (initialize_nameservers) { int r; #ifdef WIN32 r = evdns_base_config_windows_nameservers(base); #else r = evdns_base_resolv_conf_parse(base, DNS_OPTIONS_ALL, "/etc/resolv.conf"); #endif if (r == -1) { evdns_base_free_and_unlock(base, 0); return NULL; } } EVDNS_UNLOCK(base); return base; }
解決方案是編譯時增加一個 ANDROID 宏,針對 Android 平台實現讀取 dns 配置的代碼,這在我的文章《Android C 語言讀取系統屬性》中有相關解說。下面是具體的代碼:
if (initialize_nameservers) { int r; #ifdef WIN32 r = evdns_base_config_windows_nameservers(base); #elif defined(ANDROID) { int add_servers = 0; char buf[PROP_VALUE_MAX]; r = __system_property_get("net.dns1", buf); if(r >= 7) { add_servers++; evdns_base_nameserver_ip_add(base, buf); } r = __system_property_get("net.dns2", buf); if(r >= 7) { add_servers++; evdns_base_nameserver_ip_add(base, buf); } if(add_servers == 0) { evdns_base_nameserver_ip_add(base,"8.8.8.8"); } } #else r = evdns_base_resolv_conf_parse(base, DNS_OPTIONS_ALL, "/etc/resolv.conf"); #endif if (r == -1) { evdns_base_free_and_unlock(base, 0); return NULL; } }
什麼是Sencha Touch前不久基於JavaScript編寫的Ajax框架ExtJS,將現有的ExtJS整合JQTouch、Rapha?l庫,推出適用於最前沿Touc
先給大家展示下關於仿支付寶錢包首頁中帶有分割線的gridview,俗稱九宮格 的效果圖,怎麼樣是不是和你想象的一樣啊。在你的預料之中就繼續訪問以下代碼內容吧。我們都知道L
這一篇來記錄一下使用ActiveAndroid關系型數據庫進行本地對象的保存。1.ActiveAndroid的介紹該項目的github地址:https://github.
Fragment 介紹: 每個Fragment都是一個獨立的模塊,並與它所綁定的Activity精密聯系在一起,不同的Actiivty也可以使用同一個Fragment,在