鸿蒙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();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/536835.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十五、软考-系统架构设计师笔记-面向服务架构设计理论与实践

1、SOA相关概念 面向服务的架构(SOA)的定义 SOA 是一个组件模型&#xff0c;它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的&#xff0c;它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构…

Vue2(五):收集表单数据、过滤器、内置指令和自定义指令

一、回顾 总结Vue监视数据 1.Vue监视数据的原理&#xff1a; 1.vue会监视data中所有层次的数据。 2.如何监测对象中的数据?通过setter实现监视&#xff0c;且要在new Vue时就传入要监测的数据。(1&#xff09;.对象中后追加的属性&#xff0c;Vue默认不做响应式处理(2&#…

C语言从入门到熟悉------第三阶段

数组 什么是数组呢&#xff1f;顾名思义数组就是很多数的组合&#xff01;那么这些数有没有什么要求呢&#xff1f;是不是不管什么数组合在一起都是数组呢&#xff1f;第一&#xff0c;这些数的类型必须相同&#xff01;第二&#xff0c;这些数在内存中必须是连续存储的。也就…

java-集合工具类Collections

我们在使用它的时候记得导包 常见API 我们就简单看看第一第二个方法&#xff0c;代码如下&#xff0c;其余的知道用就行

LDA主题模型学习笔记

&#xff08;1&#xff09;LDA的基本介绍&#xff08;wiki&#xff09; LDA是一种典型的词袋模型&#xff0c;即它认为一篇文档是由一组词构成的一个集合&#xff0c;词与词之间没有顺序以及先后的关系。一篇文档可以包含多个主题&#xff0c;文档中每一个词都由其中的一个主题…

STM32第八节:位带操作——GPIO输出和输入

前言 我们讲了GPIO的输出&#xff0c;虽然我们使用的是固件库编程&#xff0c;但是最底层的操作是什么呢&#xff1f;对&#xff0c;我们学习过51单片机的同学肯定学习过 sbit 修改某一位的高低电平&#xff0c;从而实现对于硬件的控制。那么我们现在在STM32中有没有相似的操作…

前端面试 ===> 【Vue2】

Vue2 相关面试题总结 1. 谈谈对Vue的理解 Vue是一种用于构建用户页面的渐进式JavaScript框架&#xff0c;也是一个创建SPA单页面应用的Web应用框架&#xff0c;Vue的核心是 数据驱动试图&#xff0c;通过组件内特定的方法实现视图和模型的交互&#xff1b;特性&#xff1a;&a…

pkav之当php懈垢windows通用上传缺陷

环境&#xff1a; Windowsnginxphp 一、php源码 <?php //U-Mail demo ... if(isset($_POST[submit])){$filename $_POST[filename];$filename preg_replace("/[^\w]/i", "", $filename);$upfile $_FILES[file][name];$upfile str_replace(;,&qu…

清华把大模型用于城市规划,回龙观和大红门地区成研究对象

引言&#xff1a;参与式城市规划的新篇章 随着城市化的不断推进&#xff0c;传统的城市规划方法面临着越来越多的挑战。这些方法往往需要大量的时间和人力&#xff0c;且严重依赖于经验丰富的城市规划师。为了应对这些挑战&#xff0c;参与式城市规划应运而生&#xff0c;它强…

【文献阅读】A Fourier-based Framework for Domain Generalization(基于傅立叶的领域泛化框架)

原文地址&#xff1a;https://arxiv.org/abs/2105.11120 摘要 现代深度神经网络在测试数据和训练数据的不同分布下进行评估时&#xff0c;存在性能下降的问题。领域泛化旨在通过从多个源领域学习可转移的知识&#xff0c;从而泛化到未知的目标领域&#xff0c;从而解决这一问…

面试复盘记录(数据开发)

一、apple外包1.矩阵顺时针旋转遍历2.两表取差集 二、 一、apple外包 没问理论&#xff0c;就两个算法题。 1.矩阵顺时针旋转遍历 Given an m x n matrix, return all elements of the matrix in spiral order.Example 1:Input: matrix [[1,2,3],[4,5,6],[7,8,9]] Output: …

【LeetCode热题100】141. 环形链表(链表)

一.题目要求 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置…