鸿蒙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,直接返回。 这个函数执行完了,就会回到自己,调用自己右边的那个函数,结果又是空,又返回,回到…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
react更新页面数据,操作页面,双向数据绑定
// 路由不是组件的直接跳转use client,useEffect,useRouter,需3个结合, use client表示客户端 use client; import { Button,Card, Space,Tag,Table,message,Input } from antd; import { useEffect,useState } from react; impor…...
[QMT量化交易小白入门]-六十二、ETF轮动中简单的评分算法如何获取历史年化收益32.7%
本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。 QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。 文章目录 相关阅读1. 策略概述2. 趋势评分模块3 代码解析4 木头…...
简单聊下阿里云DNS劫持事件
阿里云域名被DNS劫持事件 事件总结 根据ICANN规则,域名注册商(Verisign)认定aliyuncs.com域名下的部分网站被用于非法活动(如传播恶意软件);顶级域名DNS服务器将aliyuncs.com域名的DNS记录统一解析到shado…...
Ansible+Zabbix-agent2快速实现对多主机监控
ansible Ansible 是一款开源的自动化工具,用于配置管理(Configuration Management)、应用部署(Application Deployment)、任务自动化(Task Automation)和编排(Orchestration…...
