1. 域名解析簡(jiǎn)介
域名解析是網(wǎng)絡(luò)開(kāi)發(fā)中經(jīng)常使用的功能之一航棱,特別是對(duì)于當(dāng)前版本的鴻蒙API,使用TCP或者UDP等網(wǎng)絡(luò)協(xié)議通訊時(shí)靠胜,只能使用確定的IP地址進(jìn)行綁定或者發(fā)送消息掉瞳,還不支持直接使用域名毕源,所以,通過(guò)域名解析得到對(duì)應(yīng)的IP地址陕习,然后再使用套接字進(jìn)行通訊霎褐,可以避免使用者記錄IP地址的困難。
在本系列的第15篇文章《鴻蒙網(wǎng)絡(luò)編程系列15-域名解析示例》中该镣,我們基于ArkTS語(yǔ)言在API 9的環(huán)境下演示了對(duì)網(wǎng)站域名進(jìn)行解析的過(guò)程冻璃,本文將使用倉(cāng)頡語(yǔ)言在API 12的環(huán)境中實(shí)現(xiàn)類似的功能。
鴻蒙封裝的網(wǎng)絡(luò)管理包损合,使用如下的方式導(dǎo)入:
import ohos.net.connection.*
connection包和域名解析相關(guān)的函數(shù)主要是如下三個(gè):
//獲取默認(rèn)激活的數(shù)據(jù)網(wǎng)絡(luò)省艳。
1. public func getDefaultNet(): NetHandle
//NetHandle類的函數(shù),使用對(duì)應(yīng)網(wǎng)絡(luò)解析主機(jī)名以獲取所有IP地址嫁审。
2. public func getAddressesByName(host: String): Array<NetAddress>
//NetHandle類的函數(shù)跋炕,使用對(duì)應(yīng)網(wǎng)絡(luò)解析主機(jī)名以獲取第一個(gè)IP地址。
3. public func getAddressByName(host: String): NetAddress
一個(gè)域名可能對(duì)應(yīng)多個(gè)IP地址律适,如果只是獲取域名對(duì)應(yīng)的IP地址辐烂,可以使用getAddressByName函數(shù),如果需要獲取域名對(duì)應(yīng)的所有IP地址捂贿,需要使用getAddressesByName函數(shù)纠修,本文要演示解析域名的所有IP地址,所以使用的是getAddressByName厂僧。
2. 域名解析演示
本示例運(yùn)行后的界面如圖所示:
輸入待解析的域名扣草,然后單擊“解析”按鈕,即可進(jìn)行解析颜屠,這里使用了百度和華為開(kāi)發(fā)者社區(qū)的域名德召,解析結(jié)果如圖所示:
可以看到,解析出了所有對(duì)應(yīng)的IP地址汽纤。
3. 域名解析示例編寫
下面詳細(xì)介紹創(chuàng)建該示例的步驟(確保DevEco Studio已安裝倉(cāng)頡插件)。
步驟1:創(chuàng)建[Cangjie]Empty Ability項(xiàng)目福荸。
步驟2:在module.json5配置文件加上對(duì)權(quán)限的聲明:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.GET_NETWORK_INFO"
}
]
這里添加了獲取網(wǎng)絡(luò)信息和訪問(wèn)互聯(lián)網(wǎng)的權(quán)限蕴坪。
步驟3:在build-profile.json5配置文件加上倉(cāng)頡編譯架構(gòu):
"cangjieOptions": {
"path": "./src/main/cangjie/cjpm.toml",
"abiFilters": ["arm64-v8a", "x86_64"]
}
步驟4:在index.cj文件里添加如下的代碼:
package ohos_app_cangjie_entry
import ohos.base.*
import ohos.component.*
import ohos.state_manage.*
import ohos.state_macro_manage.*
import std.collection.HashMap
import ohos.net.http.*
import ohos.net.connection.*
import std.collection.ArrayList
@Entry
@Component
class EntryView {
//標(biāo)題
@State
var title: String = "倉(cāng)頡版域名解析示例"
//連接、通訊歷史記錄
@State
var msgHistory: String = ''
//登錄地址
@State
var hostName: String = "www.baidu.com"
let scroller: Scroller = Scroller()
func build() {
Row {
Column {
Text(title).fontSize(14).fontWeight(FontWeight.Bold).width(100.percent).textAlign(
TextAlign.Center).padding(10)
Flex(FlexParams(justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center)) {
Text("待解析域名:").fontSize(14)
TextInput(text: hostName).onChange({
value => hostName = value
}).width(100).fontSize(11).flexGrow(1)
Button("解析").onClick {
evt => resolveHost()
}.width(70).fontSize(14).flexGrow(0)
}.width(100.percent).padding(10)
Scroll(scroller) {
Text(msgHistory).textAlign(TextAlign.Start).padding(10).width(100.percent).backgroundColor(0xeeeeee)
}.align(Alignment.Top).backgroundColor(0xeeeeee).height(300).flexGrow(1).scrollable(
ScrollDirection.Vertical).scrollBar(BarState.On).scrollBarWidth(20)
}.width(100.percent).height(100.percent)
}.height(100.percent)
}
//解析域名對(duì)應(yīng)的IP地址
func resolveHost() {
//獲取默認(rèn)的激活網(wǎng)絡(luò)
let netHandle = getDefaultNet();
var addrList = ArrayList<String>()
//遍歷解析后得到的每一個(gè)網(wǎng)絡(luò)地址并去重
for (netaddr in netHandle.getAddressesByName(this.hostName)) {
if (!addrList.contains(netaddr.address)) {
addrList.append(netaddr.address)
}
}
this.msgHistory += "解析域名[${this.hostName}]的結(jié)果:\r\n"
//輸出去重后的IP地址
for (addr in addrList) {
this.msgHistory += "${addr}\r\n"
}
}
}
步驟5:編譯運(yùn)行敬锐,可以使用模擬器或者真機(jī)背传。
步驟6:按照本文第2部分“域名解析演示”操作即可。
4. 代碼分析
在域名解析的時(shí)候台夺,使用getAddressesByName函數(shù)返回的多個(gè)IP地址有可能包括重復(fù)的地址径玖,所以在使用的時(shí)候要注意去重,本示例是通過(guò)如下的方式實(shí)現(xiàn)去重的:
var addrList = ArrayList<String>()
//遍歷解析后得到的每一個(gè)網(wǎng)絡(luò)地址并去重
for (netaddr in netHandle.getAddressesByName(this.hostName)) {
if (!addrList.contains(netaddr.address)) {
addrList.append(netaddr.address)
}
}
(本文作者原創(chuàng)颤介,除非明確授權(quán)禁止轉(zhuǎn)載)
本文源碼地址:
https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/others/DnsResolve4Cj