HarmonyOS开发实战:UDP回声服务器的实例

avatar
作者
猴君
阅读量:9

 1.回声服务器简介

回声服务器指的是这样一种服务器,它接受客户端的连接,并且把收到的数据原样返回给客户端,本文将使用UDP协议实现一个回声服务器,关于UDP通讯相关方法的介绍可以参考上一篇博文:鸿蒙网络编程-UDP通讯示例,最终应用的界面如下图所示:

cke_5125.png

2.实现思路

首先创建一个UDP实例,然后绑定到指定的端口,再订阅message事件,在处理该事件的时候,输出接收到的消息并且把该消息通过send方法发回客户端。

3.实现步骤

步骤1:创建Empty Ability项目。

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

"requestPermissions": [

      {

        "name": "ohos.permission.INTERNET"

      },

      {

        "name": "ohos.permission.GET_WIFI_INFO"

      }

    ]

这里分别添加了访问互联网和访问WIFI信息的权限。

步骤3:在Index.ets文件里添加如下的代码:

import socket from '@ohos.net.socket'; import wifiManager from '@ohos.wifiManager'; import systemDateTime from '@ohos.systemDateTime'; import util from '@ohos.util'; import hilog from '@ohos.hilog';  //执行UDP通讯的对象 let udpSocket = socket.constructUDPSocketInstance();  //说明:本地的IP地址不是必须知道的,绑定时绑定到IP:0.0.0.0即可,显示本地IP地址的目的是方便对方发送信息过来 //本地IP的数值形式 let ipNum = wifiManager.getIpInfo().ipAddress //本地IP的字符串形式 let localIp = (ipNum >>> 24) + '.' + (ipNum >> 16 & 0xFF) + '.' + (ipNum >> 8 & 0xFF) + '.' + (ipNum & 0xFF);  @Entry @Component struct Index {   //连接、通讯历史记录   @State msgHistory: string = ''   //本地端口   @State localPort: number = 9999   scroller: Scroller = new Scroller()    build() {     Row() {       Column() {         Text("UDP回声服务器")           .fontSize(14)           .fontWeight(FontWeight.Bold)           .width('100%')           .textAlign(TextAlign.Center)           .padding(10)          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {           Text("本地IP和端口:")             .width(100)             .fontSize(14)             .flexGrow(0)           Text(localIp)             .width(110)             .fontSize(14)             .flexGrow(0)           TextInput({ text: this.localPort.toString() })             .type(InputType.Number)             .onChange((value) => {               this.localPort = parseInt(value)             })             .width(80)             .flexGrow(3)            Button("绑定")             .onClick(() => {               this.bind2Port()             })             .width(80)             .fontSize(14)             .flexGrow(0)          }.width('100%')         .padding(10)          Scroll(this.scroller) {           Text(this.msgHistory)             .textAlign(TextAlign.Start)             .padding(10)             .width('100%')             .backgroundColor(0xeeeeee)         }         .align(Alignment.Top)         .backgroundColor(0xeeeeee)         .height(300)         .flexGrow(1)         .scrollable(ScrollDirection.Vertical)         .scrollBar(BarState.On)         .scrollBarWidth(20)       }       .width('100%')       .justifyContent(FlexAlign.Start)       .height('100%')     }     .height('100%')   }    //发送消息到目的ip和端口   sendMsg2Target(address: string, port: number, msg: string) {     //目的ip和端口     let remoteAddress = { address: address, port: port, family: 1 }     udpSocket.send({ data: msg, address: remoteAddress })       .then(async () => {         hilog.info(0x0000, 'sendMsg2Target', '%{public}s:%{public}d %{public}s',           remoteAddress.address, remoteAddress.port, msg)       })       .catch((e) => {         hilog.error(0x0000, 'sendMsg2Target', '%{public}s:%{public}d %{public}s',           remoteAddress.address, remoteAddress.port, e.message)       })   }    //绑定本地端口   async bind2Port() {     //本地地址     let localAddress = { address: "0.0.0.0", port: this.localPort, family: 1 }      await udpSocket.bind(localAddress)       .then(() => {         this.msgHistory = 'bind success' + "\r\n";       })       .catch((e) => {         this.msgHistory = 'bind fail' + e.message + "\r\n";       })      //收到消息时的处理     udpSocket.on("message", async (value) => {       let msg = buf2String(value.message)       let remoteIP = value.remoteInfo.address       let remotePort = value.remoteInfo.port       //对端ip地址和端口的字符串形式       let remoteAddr = "[" + remoteIP + ":" + remotePort.toString() + "]:"       let time = await getCurrentTimeString()       this.msgHistory += remoteAddr + msg + time + "\r\n"       this.scroller.scrollEdge(Edge.Bottom)        //把收到的消息发回发送方       this.sendMsg2Target(remoteIP, remotePort, msg)     })   } }  //同步获取当前时间的字符串形式 async function getCurrentTimeString() {   let time = ""   await  systemDateTime.getDate().then(     (date) => {       time = date.getHours().toString() + ":" + date.getMinutes().toString()       + ":" + date.getSeconds().toString()     }   )   return "[" + time + "]" }  //ArrayBuffer转utf8字符串 function buf2String(buf: ArrayBuffer) {   let msgArray = new Uint8Array(buf);   let textDecoder = util.TextDecoder.create("utf-8");   return textDecoder.decodeWithStream(msgArray) }

步骤4:编译运行,可以部署到模拟器或者真机上。

步骤5:配置本地端口,然后单击绑定按钮绑定到本地指定的端口即可。

步骤6:启动UDP客户端测试,这里使用PC端的一个UDP客户端程序,如下图所示:

cke_186428.jpg

先后发送了两段文字,以S开头的是服务端回送的内容,回声服务器的截图内容如下所示:

cke_280627.jpeg

4.注意事项

目前的鸿蒙系统其实不适合作为服务端使用,因为应用切换到后台后就会被挂起,这时候就起不到服务器的功能了,所以本示例需要保持在前端,否则会接收不到消息。



最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?但是又不知道从哪里下手,而且学习时频繁踩坑,最终浪费大量时间。所以本人整理了一些比较合适的鸿蒙(HarmonyOS NEXT)学习路径和一些资料的整理供小伙伴学习

点击领取→纯血鸿蒙Next全套最新学习资料

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取~~

一、鸿蒙(HarmonyOS NEXT)最新学习路线

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)…等技术知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

二、HarmonyOS Next 最新全套视频教程

三、《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

四、大厂面试必问面试题

五、鸿蒙南向开发技术

六、鸿蒙APP开发必备


完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

                        

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!