在过去很长一段时间,我都非常希望能够将OpenHarmony与HarmonyOS设备进行一个联动,但是碍于一些底层接口未完善一直无法实现。但是在前几个月,OpenHarmony3.1 带来了更多可能。本次,我将分享如何在搭载HarmonyOS的手机和搭载OpenHarmony的开发板上,实现socket对话!
0. 效果演示
1.HarmonyOS侧
1.1 新建一个JAVA工程,编写简单的测试页面
- ability_main.xml (主页面)
这是我自己编写的一个测试页面,但不是最重要的。
1.2 编写socket功能
目前,鸿蒙的Socket通信功能只能在JAVA侧实现,并且官网对相关的功能解析不够全面,但是足够实现UDP通信。
这里直接参考官网,可以快速实现Socket功能,传送门:JAVA-socket
在MainAbilitySlice中编写两个主要函数,并结合个人情况绑定到测试按键上即可。
- StartServer()
HiLog.info(LABEL_LOG, "StartServer run"); NetManager netManager = NetManager.getInstance(null); if (!netManager.hasDefaultNet()) { HiLog.error(LABEL_LOG, "netManager.hasDefaultNet() failed"); return; } NetHandle netHandle = netManager.getDefaultNet(); DatagramSocket socket = null; // 通过Socket绑定来进行数据传输 try { HiLog.info(LABEL_LOG, "wait receive data"); //通过getLocalIpAddress()快速获取本机的IP地址 InetAddress address = netHandle.getByName(getLocalIpAddress()); //端口号+主机地址 socket = new DatagramSocket(10006, address); netHandle.bindSocket(socket); /*至此绑定Socket结束*/ HiLog.info(LABEL_LOG, "绑定成功"); /*监听函数*/ byte[] buffer = new byte[1024]; DatagramPacket response = new DatagramPacket(buffer, buffer.length); while (true) { //接收数据 socket.receive(response); int len = response.getLength(); HiLog.info(LABEL_LOG, "接收成功"); //将数据打印到屏幕上 s = new String(buffer, StandardCharsets.UTF_8).substring(0, len); //一个textfield组件 text.setText(s); HiLog.info(LABEL_LOG, "receive data: " + s); } } catch (IOException e) { HiLog.error(LABEL_LOG, "rev IOException: "); } }
- sendMessage()
NetManager netManager = NetManager.getInstance(null); if (!netManager.hasDefaultNet()) { HiLog.error(LABEL_LOG, "netManager.hasDefaultNet() failed"); return; } NetHandle netHandle = netManager.getDefaultNet(); // 通过Socket绑定来进行数据传输 DatagramSocket socket = null; try { //从textfield组件获取用户输入的对端ip地址 HOST = iptf.getText(); InetAddress address = netHandle.getByName(HOST); socket = new DatagramSocket(); netHandle.bindSocket(socket); /*至此 已绑定对端Socket*/ //从一个textfield组件获取用户输入的要发送的信息。 String data = new String(sendtf.getText()); //这里默认还是发送至对端的10006端口 DatagramPacket request = new DatagramPacket(data.getBytes( StandardCharsets.UTF_8), data.length(), address, PORT); // buffer赋值 // 发送数据 socket.send(request); HiLog.info(LABEL_LOG, "send data: " + data); } catch (IOException e) { HiLog.error(LABEL_LOG, "send IOException: "); } finally { if (null != socket) { } }
- getlocalip()
private String getLocalIpAddress() { WifiDevice wifiDevice = WifiDevice.getInstance(getContext()); Optional
ipInfo = wifiDevice.getIpInfo(); int ip = ipInfo.get().getIpAddress(); return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "." + (ip >> 24 & 0xFF); } 至此,接收信息和发送信息的函数都编写完了。但并没有结束,这样的函数并不能跑在UI线程上,我们必须让其在其他线程上运作,那必须请出我们最爱的EventRunner.
1.3 编写Mythread类
EventRunner传送门
package com.example.hoop.util; import ohos.eventhandler.EventHandler; import ohos.eventhandler.EventRunner; public class Mythread { public static void inUI(Runnable runnable) { //返回主线程 EventRunner runner = EventRunner.getMainEventRunner(); EventHandler eventHandler = new EventHandler(runner); eventHandler.postSyncTask(runnable); } public static void inBG(Runnable runnable) { EventRunner runner = EventRunner.create(true); EventHandler eventHandler = new EventHandler(runner); //投递任务,我们的Socket函数应该投递于此。 eventHandler.postTask(runnable, 0, EventHandler.Priority.IMMEDIATE); } }
- 将任务投递给EventRunner
只需要将刚刚的两个主要函数投递就行了
private void sendMessage() { Mythread.inBG(new Runnable() { @Override public void run() { NetManager netManager = NetManager.getInstance(null); if (!netManager.hasDefaultNet()) { HiLog.error(LABEL_LOG,"netManager.hasDefaultNet() failed"); return; } NetHandle netHandle = netManager.getDefaultNet(); // 通过Socket绑定来进行数据传输 DatagramSocket socket = null; try { //从textfield组件获取用户输入的对端ip地址 HOST=iptf.getText(); InetAddress address = netHandle.getByName(HOST); socket = new DatagramSocket(); netHandle.bindSocket(socket); /*至此 已绑定对端Socket*/ //从一个textfield组件获取用户输入的要发送的信息。 String data = new String(sendtf.getText()); //这里默认还是发送至对端的10006端口 DatagramPacket request = new DatagramPacket(data.getBytes(StandardCharsets.UTF_8), data.length(), address, PORT); // buffer赋值 // 发送数据 socket.send(request); HiLog.info(LABEL_LOG,"send data: " + data); } catch (IOException e) { HiLog.error(LABEL_LOG,"send IOException: "); } finally { if (null != socket) { } } } }); } private void StartServer() { Mythread.inBG(new Runnable() { @Override public void run() { HiLog.info(LABEL_LOG,"StartServer run"); NetManager netManager = NetManager.getInstance(null); if (!netManager.hasDefaultNet()) { HiLog.error(LABEL_LOG,"netManager.hasDefaultNet() failed"); return; } NetHandle netHandle = netManager.getDefaultNet(); DatagramSocket socket = null; // 通过Socket绑定来进行数据传输 try { HiLog.info(LABEL_LOG,"wait receive data"); //通过getLocalIpAddress()快速获取本机的IP地址 InetAddress address = netHandle.getByName(getLocalIpAddress()); //端口号+主机地址 socket = new DatagramSocket(10006, address); netHandle.bindSocket(socket); /*至此绑定Socket结束*/ HiLog.info(LABEL_LOG,"绑定成功"); /*监听函数*/ byte[] buffer = new byte[1024]; DatagramPacket response = new DatagramPacket(buffer, buffer.length); while(true){ //接收数据 socket.receive(response); int len = response.getLength(); HiLog.info(LABEL_LOG,"接收成功"); //将数据打印到屏幕上 s = new String(buffer, StandardCharsets.UTF_8).substring(0, len); Mythread.inUI(new Runnable() { @Override public void run() { //一个textfield组件 text.setText(s); } }); HiLog.info(LABEL_LOG,"receive data: " + s); } } catch (IOException e) { HiLog.error(LABEL_LOG,"rev IOException: " ); } } }); }
2.OpenHarmony侧
2.1 新建工程,编写测试页面
- index.hml
{{ title }} 本机IP{{getIpAddress()}} 2.2 编写Socket功能
OpenHarmony-Socket
import socket from '@ohos.net.socket'; import wifi from '@ohos.wifi'; export default { data: { title: "等待新的消息...", tcp: socket.constructTCPSocketInstance(), remoteip:'none', localip:'none', msg:"A NEW WORLD", udp:socket.constructUDPSocketInstance(), }, onInit() { this.getIpAddress(); this.creatScoket(); this.title="暂无新消息" }, //创建udpSocket 默认端口10006 creatScoket: async function(){ this.udp.bind({address: this.getIpAddress(), port: 10006, family: 1}, err => { if (err) { console.info('bind fail'); this.title='bind fail' return; } this.title='bind success'; console.info('bind success'); }) // this.tcp.bind({address: this.localip, port: 10006,family: 1}, err => { // if (err) { // console.log('bind fail'); // this.title='bind fail'; // return; // } // this.title='bind success'; // console.log('bind success'); // }) //监听收到的信息 打印到屏幕上 this.udp.on('message', value => { let buffer = value.message; let dataView = new DataView(buffer); let str = ""; for (let i = 0;i < dataView.byteLength; ++i) { str += String.fromCharCode(dataView.getUint8(i)) } this.title =str; }); }, sendMessage: async function(){ // let promise1 = this.udp.connect({ address: {address: this.remoteip, port: 10006, family: 1} , timeout: 6000}); // promise1.then(() => { // console.log('connect success'); // let promise2 =this.udp.send({ // data:this.msg // }); // promise2.then(() => { // console.log('send success'); // }).catch(err => { // console.log('send fail'); // }); // }).catch(err => { // this.title='connect fail'; // console.log('connect fail'); // }); //发送信息 let promise = this.udp.send({ data:this.msg, address: { address:this.remoteip, port:10006, family:1 } }); promise.then(() => { this.title='send success'; console.info('send success'); }).catch(err => { this.title='send fail' console.info('send fail'); }); }, newlocalip(e){ this.localip = e.value; this.title = e.value; }, newremoteip(e){ this.remoteip = e.value; }, newMessage(e){ this.msg=e.value; this.title=e.value; }, //获取本机ip地址 getIpAddress(){ let ip=wifi.getIpInfo().ipAddress; this.localip = (ip >> 24 & 0xFF)+"."+ ((ip >> 16) & 0xFF)+"."+((ip >> 8) & 0xFF)+"."+(ip & 0xFF); }, }
3.测试
这里为了便于测试,我们最好下载一个网络调试助手
网络调试助手
3.1结果
- OpenHarmony侧
- HarmonyOS侧
- OpenHarmony&HarmonyOS 联动
4 结语
实现了OpenHarmony与HarmonyOS的简单通讯后,应用开发,软硬件联动都有了更多的可能性。目前可能存在一些稳定性,不完整性问题,未来两侧基础功能不断完善之后,将会变得更有趣也更好用。如有明显错误,希望读者能够积极提出,我会尽力完善。
- OpenHarmony侧
- index.hml
- 将任务投递给EventRunner
- getlocalip()
- sendMessage()
- StartServer()
猜你喜欢
- 11天前(江西启动“唱游江西”计划)江西启动“唱游江西”计划
- 11天前(哈弗h9优惠9万是真的吗)热浪来袭,哈弗H9超值补贴火热加码
- 11天前(河南省文旅大会精神)2025河南省文化旅游发展大会新闻发布会在郑州召开
- 11天前(“清透会呼吸”轻松拿捏春日出游氛围感)“清透会呼吸”轻松拿捏春日出游氛围感
- 11天前(曼谷丽思卡尔顿公寓价格)曼谷丽思卡尔顿酒店盛大启幕,开创泰国奢华雅致新纪元
- 11天前(当科学邂逅喜剧:科技馆喜剧嘉年华背后的"文旅破壁者")当科学邂逅喜剧:科技馆喜剧嘉年华背后的"文旅破壁者"
- 11天前(万豪旅享家活动2021)精彩上新,漫享夏日----跟随万豪旅享家新开酒店解锁夏日旅行灵感
- 11天前(2025年安徽省“百场黄梅唱响百家景区”示范展示启动)2025年安徽省“百场黄梅唱响百家景区”示范展示启动
- 11天前(新西兰登陆《我的世界》!全球首个目的地游戏模组震撼上线)新西兰登陆《我的世界》!全球首个目的地游戏模组震撼上线
- 11天前(泸沽湖大酒店地址)泸沽湖岚岳酒店盛大开业|以摩梭文化为魂,打造高端度假新地标
网友评论
- 搜索
- 最新文章
- (2020广州车展哈弗)你的猛龙 独一无二 哈弗猛龙广州车展闪耀登场
- (哈弗新能源suv2019款)智能科技颠覆出行体验 哈弗重塑新能源越野SUV价值认知
- (2021款全新哈弗h5自动四驱报价)新哈弗H5再赴保障之旅,无惧冰雪护航哈弗全民电四驱挑战赛
- (海南航空现况怎样)用一场直播找到市场扩张新渠道,海南航空做对了什么?
- (visa jcb 日本)优惠面面俱到 JCB信用卡邀您畅玩日本冰雪季
- (第三届“堡里有年味·回村过大年”民俗花灯会活动)第三届“堡里有年味·回村过大年”民俗花灯会活动
- (展示非遗魅力 长安启源助力铜梁龙舞出征)展示非遗魅力 长安启源助力铜梁龙舞出征
- (阿斯塔纳航空公司)阿斯塔纳航空机队飞机数量增至50架
- (北京香港航班动态查询)香港快运航空北京大兴新航线今日首航
- (我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉)我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉
- 热门文章