鸿蒙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,直接返回。 这个函数执行完了,就会回到自己,调用自己右边的那个函数,结果又是空,又返回,回到…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
