鸿蒙Socket通信示例(TCP通信)
前言
DevEco Studio版本:4.0.0.600
参考链接:OpenHarmony Socket
效果

TCPSocket
1、bind绑定本地IP地址
private bindTcpSocket() {let localAddress = resolveIP(wifi.getIpInfo().ipAddress)console.info("111111111 localAddress: " + localAddress);//bind本地地址tcpSocket.bind({ address: localAddress }).then(() => {console.info("111111111 绑定Tcp成功");}).catch(err => {console.info("111111111 绑定Tcp失败,原因: " + err);});
}
2、设置tcpSocket的监听
private tcpSocketListener() {tcpSocket.on('connect', () => {this.connectMessage = '已连接'console.info("111111111 监听: 连接成功");});tcpSocket.on('message', (value: {message: ArrayBuffer,remoteInfo: socket.SocketRemoteInfo}) => {this.messageReceive = this.messageReceive + this.resolveArrayBuffer(value.message) + "\n"console.info("111111111 接收服务器的数据: " + this.messageReceive);});tcpSocket.on('close', () => {this.connectMessage = '未连接'console.info("111111111 监听:关闭连接")});
}
3、连接服务器
private tcpSocketConnect() {//开始连接tcpSocket.connect({address: { address: connectAddress.address, port: connectAddress.port, family: connectAddress.family },timeout: 6000}).then(() => {console.info("111111111 tcpSocketConnect:连接成功");let tcpExtraOptions: socket.TCPExtraOptions = {keepAlive: true, //是否保持连接。默认为falseOOBInline: true, //是否为OOB内联。默认为falseTCPNoDelay: true, //TCPSocket连接是否无时延。默认为falsesocketLinger: {on: true,linger: 10}, //socket是否继续逗留。- on:是否逗留(true:逗留;false:不逗留)。- linger:逗留时长,单位毫秒(ms),取值范围为0~65535。当入参on设置为true时,才需要设置。receiveBufferSize: 1000, //接收缓冲区大小(单位:Byte),默认为0sendBufferSize: 1000, //发送缓冲区大小(单位:Byte),默认为0。reuseAddress: true, //是否重用地址。默认为false。socketTimeout: 3000//套接字超时时间,单位毫秒(ms),默认为0。}tcpSocket.setExtraOptions(tcpExtraOptions, (err: BusinessError) => {if (err) {console.log('111111111 setExtraOptions 失败');return;}console.log('111111111 setExtraOptions 成功');});}).catch((error) => {console.info("111111111 tcpSocketConnect 连接失败,原因: " + JSON.stringify(error));})
}
4、发送数据内容
private sendMessage() {tcpSocket.getState().then((data) => {console.info("111111111 连接状态: " + JSON.stringify(data))//已连接if (data.isConnected) {//发送消息tcpSocket.send({ data: `${this.inputContent}\n`, encoding: 'UTF-8' }).then(() => {this.messageReceive = this.messageReceive + "发送:" + this.inputContent + "\n"console.info("111111111 消息发送成功");}).catch((error) => {console.info("111111111 消息发送失败,原因:" + JSON.stringify(error));})} else {console.info("111111111 没有连接");this.connectMessage = '未连接,服务器断了'}})
}
5、结束释放资源
private tcpSocketRelease() {tcpSocket.off("message")tcpSocket.off("connect")tcpSocket.off("close")tcpSocket.close()tcpSocket = null
}
6、UI实现
build() {Column() {TextInput({ placeholder: '请输入用户名', text: '测试数据:Test' }).width('100%').margin({ top: 20, bottom: 20 }).onChange((value: string) => {this.inputContent = value})Button('发送数据').width('100%').margin({ top: 20, bottom: 20 }).onClick(() => {this.sendMessage()})Text() {Span('连接状态:')Span(this.connectMessage).fontColor(Color.Red)}Scroll() {Column() {Text() {Span('内容:\n')Span(this.messageReceive).fontColor(Color.Pink)}}.width('100%').alignItems(HorizontalAlign.Start)}.width("100%").alignSelf(ItemAlign.Start).flexShrink(1).margin({ top: 15 })}.alignItems(HorizontalAlign.Start).padding({ left: 15, right: 15 }).width('100%').height('100%')
}
详细代码
1、Index.ets
import socket from '@ohos.net.socket';
import wifi from '@ohos.wifi';
import { BusinessError } from '@ohos.base';
import { resolveIP } from '../utils/IpUtil';
import util from '@ohos.util';//tcp连接对象
let tcpSocket = socket.constructTCPSocketInstance();//连接服务器的地址和端口
let connectAddress = {address: '10.65.XX.XX', //要通信的 PC地址,CMD--->ipconfig查看family: 1,port: 6666
}@Entry
@Component
struct Index {@State connectMessage: string = '未连接'@State messageReceive: string = ''@State inputContent: string = ''aboutToAppear() {this.tcpSocketListener()this.bindTcpSocket()}onPageShow() {this.tcpSocketConnect()}onPageHide() {this.tcpSocketRelease()}build() {Column() {TextInput({ placeholder: '请输入用户名', text: '测试数据:Test' }).width('100%').margin({ top: 20, bottom: 20 }).onChange((value: string) => {this.inputContent = value})Button('发送数据').width('100%').margin({ top: 20, bottom: 20 }).onClick(() => {this.sendMessage()})Text() {Span('连接状态:')Span(this.connectMessage).fontColor(Color.Red)}Scroll() {Column() {Text() {Span('内容:\n')Span(this.messageReceive).fontColor(Color.Pink)}}.width('100%').alignItems(HorizontalAlign.Start)}.width("100%").alignSelf(ItemAlign.Start).flexShrink(1).margin({ top: 15 })}.alignItems(HorizontalAlign.Start).padding({ left: 15, right: 15 }).width('100%').height('100%')}/*** tcp连接状态和消息监听*/private tcpSocketListener() {tcpSocket.on('connect', () => {this.connectMessage = '已连接'console.info("111111111 监听: 连接成功");});tcpSocket.on('message', (value: {message: ArrayBuffer,remoteInfo: socket.SocketRemoteInfo}) => {this.messageReceive = this.messageReceive + this.resolveArrayBuffer(value.message) + "\n"console.info("111111111 接收服务器的数据: " + this.messageReceive);});tcpSocket.on('close', () => {this.connectMessage = '未连接'console.info("111111111 监听:关闭连接")});}/*** 绑定Tcp本地地址* bind的IP为'localhost'或'127.0.0.1'时,只允许本地回环接口的连接,即服务端和客户端运行在同一台机器上*/private bindTcpSocket() {let localAddress = resolveIP(wifi.getIpInfo().ipAddress)console.info("111111111 localAddress: " + localAddress);//bind本地地址tcpSocket.bind({ address: localAddress }).then(() => {console.info("111111111 绑定Tcp成功");}).catch(err => {console.info("111111111 绑定Tcp失败,原因: " + err);});}/*** 发送消息数据*/private sendMessage() {tcpSocket.getState().then((data) => {console.info("111111111 连接状态: " + JSON.stringify(data))//已连接if (data.isConnected) {//发送消息tcpSocket.send({ data: `${this.inputContent}\n`, encoding: 'UTF-8' }).then(() => {this.messageReceive = this.messageReceive + "发送:" + this.inputContent + "\n"console.info("111111111 消息发送成功");}).catch((error) => {console.info("111111111 消息发送失败,原因:" + JSON.stringify(error));})} else {console.info("111111111 没有连接");this.connectMessage = '未连接,服务器断了'}})}/*** 连接服务器*/private tcpSocketConnect() {//开始连接tcpSocket.connect({address: { address: connectAddress.address, port: connectAddress.port, family: connectAddress.family },timeout: 6000}).then(() => {console.info("111111111 tcpSocketConnect:连接成功");let tcpExtraOptions: socket.TCPExtraOptions = {keepAlive: true, //是否保持连接。默认为falseOOBInline: true, //是否为OOB内联。默认为falseTCPNoDelay: true, //TCPSocket连接是否无时延。默认为falsesocketLinger: {on: true,linger: 10}, //socket是否继续逗留。- on:是否逗留(true:逗留;false:不逗留)。- linger:逗留时长,单位毫秒(ms),取值范围为0~65535。当入参on设置为true时,才需要设置。receiveBufferSize: 1000, //接收缓冲区大小(单位:Byte),默认为0sendBufferSize: 1000, //发送缓冲区大小(单位:Byte),默认为0。reuseAddress: true, //是否重用地址。默认为false。socketTimeout: 3000//套接字超时时间,单位毫秒(ms),默认为0。}tcpSocket.setExtraOptions(tcpExtraOptions, (err: BusinessError) => {if (err) {console.log('111111111 setExtraOptions 失败');return;}console.log('111111111 setExtraOptions 成功');});}).catch((error) => {console.info("111111111 tcpSocketConnect 连接失败,原因: " + JSON.stringify(error));})}/*** 解析ArrayBuffer*/private resolveArrayBuffer(message: ArrayBuffer): string {let view = new Uint8Array(message);let textDecoder = util.TextDecoder.create()let str = textDecoder.decodeWithStream(view);console.info("111111111 message 缓存内容: " + str)return str;}/*** 关闭Socket监听和连接,释放资源*/private tcpSocketRelease() {tcpSocket.off("message")tcpSocket.off("connect")tcpSocket.off("close")tcpSocket.close()tcpSocket = null}
}
2、IpUtil.ets
export function resolveIP(ip: number): string {if (ip < 0 || ip > 0xFFFFFFFF) {throw ('The number is not normal!');}return (ip >>> 24) + '.' + (ip >> 16 & 0xFF) + '.' + (ip >> 8 & 0xFF) + '.' + (ip & 0xFF);
}
3、module.json5配置
因为涉及到网络访问,需要配置网络权限,在module.json5中配置
"requestPermissions": [{"name": "ohos.permission.INTERNET" //联网},{"name": "ohos.permission.GET_NETWORK_INFO" //获取网络相关信息},{"name": "ohos.permission.SET_NETWORK_INFO" //设置网络相关信息},{"name": "ohos.permission.GET_WIFI_INFO" //获取wifi相关信息}
]

服务器端Java代码
package org.example;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class SocketService {public static void main(String[] args) {int port = 6666;try {// 创建ServerSocket对象,指定监听的端口号ServerSocket serverSocket = new ServerSocket(port);while (true) {Socket clientSocket = serverSocket.accept();System.out.println("客户端连接: " + clientSocket.getInetAddress().getHostAddress());BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);String message;while ((message = reader.readLine()) != null) {System.out.println("从客户端接收到的消息: " + message);writer.println("回复: " + message);}reader.close();writer.close();clientSocket.close();System.out.println("连接断开");}} catch (Exception e) {e.printStackTrace();}}
}
相关文章:
鸿蒙Socket通信示例(TCP通信)
前言 DevEco Studio版本:4.0.0.600 参考链接:OpenHarmony Socket 效果 TCPSocket 1、bind绑定本地IP地址 private bindTcpSocket() {let localAddress resolveIP(wifi.getIpInfo().ipAddress)console.info("111111111 localAddress: " …...
yolov5-v6.0详细解读
yolov5-v6.0详细解读 一、yolov5版本介绍二、网络结构2.1 Backbone特征提取部分2.1.1 ConvBNSiLU模块2.1.2 C3模块2.1.2.1 BottleNeck模块 2.1.3 SPPF模块 2.2 Neck特征融合部分2.2.1 FPN2.2.2 PANet 2.3Head模块 三、目标框回归3.1 yolo标注格式3.2 yolov4目标回归框3.3 yolov…...
FPGA - 单总线协议(one-wire)
1,简介 单总线(one-wire)是美国 DALLAS 公司推出的外围串行扩展总线技术,与 SPI、I2C 等串行数据通信方式不同,它采用单根信号线,既传输时钟又传输数据,而且数据传输是双向的。它具有节省 I/O口…...
python的函数与类的定义
目录 1.函数 1.函数的定义 2.输入参数与输出参数的类型 3.输入和输出多个参数 1.普通参数 2.含有任意数量的参数 3.关键字参数 4.普通参数与多个参数的结合 2.类 1.类的定义 2.类的实例化 3.继承 1.函数 1.函数的定义 def 函数名(输入参数): 文档字符串 函数体 …...
Parade Series - WebRTC ( < 300 ms Low Latency ) T.B.D
Parade Series - FFMPEG (Stable X64) C:\Conda\parading-cam>ffmpeg -f dshow -i video"Surface Camera Front" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -an -rtsp_transport tcp -f rtsp://127.0.0.1:8554/cam0801...
【ARM】MDK在programming algorithm界面添加FLM
【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 解决在programming algorithm界面中无法添加想要的Flash编程算法的问题 2、 问题场景 在对于Debug进行Flash Download进行配置的时候,在programming algorithm界面中有对应的Flash编程算法。可以通过…...
springmvc学习笔记1
springmvc学习笔记part1 总概述图创建步骤创建project并在父工程中导入配置类添加为web工程检查maven配置写handller方法写配置类SpringMVC环境搭建项目部署关键步骤总结 具体设置路径设置注解接收参数(重点param参数接收路径参数接收json参数接收请求头接收和cooki…...
力扣106 从中序与后续遍历序列构造二叉树
文章目录 题目描述解题思路代码 题目描述 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7], …...
数字逻辑-时序逻辑电路一
一、实验目的 (1)熟悉触发器的逻辑功能及特性。 (2)掌握集成D和JK触发器的应用。 (3)掌握时序逻辑电路的分析和设计方法。 二、实验仪器及材料 三、实验内容及步骤 1、用D触发器(74LS74&am…...
web 课程
文章目录 格式图片超链接书签链接表格例子横跨束跨 格式 <br /> <br/> #换行图片 <img> 标签是用于在网页中嵌入图像的 HTML 标签,它有一些属性可以用来控制图像的加载、显示和交互。以下是对 <img> 标签常用属性的详细介绍:…...
工业园区智慧水电设备管控系统
在现代工业园区中,水电设备的管控系统起着至关重要的作用。这些系统不仅仅是简单的机械装置,它们更是一种智慧的结合,为工业生产提供了可靠的保障和高效的管理。让我们一起来探索工业园区智慧水电设备管控系统的奥秘。 我们来看看水电设备的…...
Git之版本回退
文章转载于:https://www.jianshu.com/p/3020740561a8 以前,如果是要去除某一块功能,我都是选择性删除,选择性注释,然后前后逻辑各种查看,各种比较。每一次,改完这些我总感觉心好累啊!…...
「jQuery系列」jQuery 校验表单(Validate)
文章目录 一、校验表单(Validate)1. 基本用法2. 验证规则3. 国际化4. 插件扩展 二、Validate常用方法1. 基本验证2. 自定义验证规则3. 远程验证(通过 AJAX)4. 提交处理(submitHandler)5. 忽略某些元素的验证…...
【Java设计模式】十九、中介者模式
文章目录 1、中介者模式2、案例3、总结 1、中介者模式 如图: 同事类之间关联较多时,整体出现网状结构,耦合度极高。一个对象一变动,好多对象都得改。若变为右边的星形结构,则一个类的变动,只影响自身与中介…...
这个学习Python的神仙网站,后悔没早点发现
Python 作为时下最流行的编程语言,很多初学者都将它作为自学编程的首选。不管是有编程经验的开发者,还是新手小白,在这个 AIGC 时代, Python 都可以带你探索新世界。 入门 Python 绝非难事,但如何让自己坚持学下去是如…...
牛津大学“领域驱动设计”课程
领域驱动设计(“DDD”)是一种专注于系统领域而不是技术的软件设计方法。重点是构建共享的心理模型并以尽可能简单的方式在代码中表示该领域模型。数据库存储、框架等技术细节被认为是设计的次要方面。该模块将重点关注 DDD 和一般设计以及相关主题&#…...
Redisson分布式锁解决方案
官方地址 官网: https://redisson.org github: https://github.com/redisson/redisson 基于setnx实现的分布式锁存在的问题 redisson分布式锁原理 不可重入: 利用hash结构记录线程id和重入次数不可重试: 利用信号量和PubSub功能实现等待、唤醒, 获取锁失败的重试机制超时释放…...
linux命令深入研究——cat
cat命令,“猫”,可以理解为瞄一眼文件内容,其中可以用重定向符号对文件进行一些修改,如增加,删除文件内容,其命令参数如-n,-s,-b可以输出带有行号的行 如果想要快速删除文件内容&…...
代码随想录算法训练营第40天|343. 整数拆分、96.不同的二叉搜索树
343. 整数拆分 题目链接:link 文章讲解:link 视频讲解:link 一、做题感受&第一想法 其实第一反应是回溯……但感觉每层的集合都会很繁琐 二、学习文章后收获 1.动态规划思路 动规五要素分析 dp和i的定义:dp[i]指把i拆分后最…...
二叉树算法
递归序 每个节点都能回到3次! 相当于2执行完然后返回了代码会往下走,来到3节点 小总结: 也就是4节点先来到自己一次,不会执行if,先调用自己左边的那个函数,但是是null,直接返回。 这个函数执行完了,就会回到自己,调用自己右边的那个函数,结果又是空,又返回,回到…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...
python打卡第47天
昨天代码中注意力热图的部分顺移至今天 知识点回顾: 热力图 作业:对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图,展示模…...
表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...
