写点什么

鸿蒙网络编程系列 42- 仓颉版域名解析示例

作者:长弓三石
  • 2024-11-01
    广东
  • 本文字数:2450 字

    阅读完需:约 8 分钟

1. 域名解析简介

域名解析是网络开发中经常使用的功能之一,特别是对于当前版本的鸿蒙 API,使用 TCP 或者 UDP 等网络协议通讯时,只能使用确定的 IP 地址进行绑定或者发送消息,还不支持直接使用域名,所以,通过域名解析得到对应的 IP 地址,然后再使用套接字进行通讯,可以避免使用者记录 IP 地址的困难。


在本系列的第 15 篇文章《鸿蒙网络编程系列 15-域名解析示例》中,我们基于 ArkTS 语言在 API 9 的环境下演示了对网站域名进行解析的过程,本文将使用仓颉语言在 API 12 的环境中实现类似的功能。


鸿蒙封装的网络管理包,使用如下的方式导入:


import ohos.net.connection.*
复制代码


connection 包和域名解析相关的函数主要是如下三个:


//获取默认激活的数据网络。1. public func getDefaultNet(): NetHandle
//NetHandle类的函数,使用对应网络解析主机名以获取所有IP地址。2. public func getAddressesByName(host: String): Array<NetAddress>
//NetHandle类的函数,使用对应网络解析主机名以获取第一个IP地址。3. public func getAddressByName(host: String): NetAddress
复制代码


一个域名可能对应多个 IP 地址,如果只是获取域名对应的 IP 地址,可以使用 getAddressByName 函数,如果需要获取域名对应的所有 IP 地址,需要使用 getAddressesByName 函数,本文要演示解析域名的所有 IP 地址,所以使用的是 getAddressByName。

2. 域名解析演示

本示例运行后的界面如图所示:



输入待解析的域名,然后单击“解析”按钮,即可进行解析,这里使用了百度和华为开发者社区的域名,解析结果如图所示:



可以看到,解析出了所有对应的 IP 地址。

3. 域名解析示例编写

下面详细介绍创建该示例的步骤(确保 DevEco Studio 已安装仓颉插件)。


步骤 1:创建[Cangjie]Empty Ability 项目。


步骤 2:在 module.json5 配置文件加上对权限的声明:


"requestPermissions": [      {        "name": "ohos.permission.INTERNET"      },      {        "name": "ohos.permission.GET_NETWORK_INFO"      }    ]
复制代码


这里添加了获取网络信息和访问互联网的权限。


步骤 3:在 build-profile.json5 配置文件加上仓颉编译架构:


"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.HashMapimport ohos.net.http.*import ohos.net.connection.*import std.collection.ArrayList
@Entry@Componentclass EntryView { //标题 @State var title: String = "仓颉版域名解析示例" //连接、通讯历史记录 @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) }
//解析域名对应的IP地址 func resolveHost() { //获取默认的激活网络 let netHandle = getDefaultNet();
var addrList = ArrayList<String>() //遍历解析后得到的每一个网络地址并去重 for (netaddr in netHandle.getAddressesByName(this.hostName)) { if (!addrList.contains(netaddr.address)) { addrList.append(netaddr.address) } } this.msgHistory += "解析域名[${this.hostName}]的结果:\r\n" //输出去重后的IP地址 for (addr in addrList) { this.msgHistory += "${addr}\r\n" } }}
复制代码


步骤 5:编译运行,可以使用模拟器或者真机。


步骤 6:按照本文第 2 部分“域名解析演示”操作即可。

4. 代码分析

在域名解析的时候,使用 getAddressesByName 函数返回的多个 IP 地址有可能包括重复的地址,所以在使用的时候要注意去重,本示例是通过如下的方式实现去重的:


 var addrList = ArrayList<String>()        //遍历解析后得到的每一个网络地址并去重        for (netaddr in netHandle.getAddressesByName(this.hostName)) {            if (!addrList.contains(netaddr.address)) {                addrList.append(netaddr.address)            }        }
复制代码


(本文作者原创,除非明确授权禁止转载)


本文源码地址:


https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/others/DnsResolve4Cj


本系列源码地址:


https://gitee.com/zl3624/harmonyos_network_samples


发布于: 刚刚阅读数: 6
用户头像

长弓三石

关注

还未添加个人签名 2024-10-16 加入

二十多年软件开发经验的软件架构师,华为HDE、华为云HCDE、仓颉语言CLD、CCS,著有《仓颉语言网络编程》、《仓颉语言元编程》、《仓颉语言实战》、《鲲鹏架构入门与实战》等书籍,清华大学出版社出版。

评论

发布
暂无评论
鸿蒙网络编程系列42-仓颉版域名解析示例_DevEco Studio_长弓三石_InfoQ写作社区