当前位置: 首页 > article >正文

鸿蒙本地模拟器 模拟TCP服务端的过程

鸿蒙模拟器模拟TCP服务端的过程涉及几个关键步骤,主要包括创建TCPSocketServer实例、绑定IP地址和端口、监听连接请求、接收和发送数据以及处理连接事件。以下是详细的模拟过程:
**1.创建TCPSocketServer实例:**首先,需要导入鸿蒙的socket模块,并创建一个TCPSocketServer对象。这个对象将用于管理TCP连接。

**2.绑定IP地址和端口:**通过调用listen()方法,将TCPSocketServer实例绑定到本地IP地址和端口上。这样,服务端就可以监听指定端口上的连接请求。

**3.监听连接请求:**服务端通过订阅TCPSocketServer的connect事件来监听客户端的连接请求。当客户端尝试连接时,服务端会接收到一个连接事件。

**4.接收和发送数据:**一旦客户端和服务端建立连接,服务端会返回一个TCPSocketConnection对象,用于与客户端进行数据通信。服务端可以通过订阅TCPSocketConnection的message事件来接收客户端发送的数据,并通过调用send()方法来向客户端发送数据。

**5.处理连接事件:**服务端还需要处理其他事件,如close和error,以管理连接的生命周期和错误处理。

**6.UI效果展示:**在模拟器上,服务端接收到的控制命令可以通过UI界面展示。例如,当客户端发送一个“开灯”命令时,服务端的UI界面会相应地更新灯的状态,或者通过改变颜色或显示图片来模拟灯的开启。

**7.端口映射和转发:**为了使服务端能够在模拟器上正确地与外部客户端通信,可能需要进行端口映射和转发。这通常通过命令行工具如netsh或鸿蒙的HDC命令来实现,将模拟器的端口映射到主机的端口上。

上诉步骤中,1-6的步骤可以根据开发者文档的TCP服务端实现操作,并且直接通过本地模拟器运行项目即可。例如以下案例:

/**
 * 1.导入 socket 模块
 */
import { socket } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';

/**
 * 2.创建 TCPSocketServer
 * 创建一个 TCPSocketServer 连接,返回一个 TCPSocketServer 对象。
 */
let tcpServer: socket.TCPSocketServer = socket.constructTCPSocketServerInstance();

class SocketInfo {
  message: ArrayBuffer = new ArrayBuffer(1);
  remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo;
}

@Entry
@Component
struct Index {
  @State showDatas: string[] = [] //用于接收客服端发送的消息
  @State serverLocalIp: string = '127.0.0.1'
  @State serverPort: number = 8000
  @State serverData:string = '服务端发送的信息'
  private connectState: boolean = false
  private tcpSocketConnection ?: socket.TCPSocketConnection

  async listenServer(serverIp: string, serverPort: number) {
    let ipAddress: socket.NetAddress = {
      address: serverIp,
      port: serverPort,
    }
    // 绑定IP:Port、监听并启动服务,接收客户端的连接请求
    tcpServer.listen(ipAddress).then(() => {
      console.info('===listen success===');
      tcpServer.on("connect", (tcpConnection: socket.TCPSocketConnection) => {
        console.info("===connect success====")
        this.connectState = true
        this.tcpSocketConnection = tcpConnection

        tcpConnection.on("message", (data: SocketInfo) => {
          console.info("====receive message====")
          let buffer = data.message;
          let dataView = new DataView(buffer);
          let messageData = "";
          for (let i = 0; i < dataView.byteLength; ++i) {
            messageData += String.fromCharCode(dataView.getUint8(i));
          }
          this.showDatas.push('客户端:' + messageData)
        });
        // 订阅TCPSocketConnection相关的事件
        tcpConnection.on("close", () => {
          console.info("===断开连接===");
        });
      })
    }).catch((err: BusinessError) => {
      console.info('listen fail');
    });}

  async sendData(message: string) {
    if (this.connectState) { //连接成功才可发送数据
      // 服务端给连接的客户端发送信息
      let tcpSendOptions: socket.TCPSendOptions = {} as socket.TCPSendOptions;
      tcpSendOptions.data = message
      this.tcpSocketConnection?.send(tcpSendOptions).then(() => {
        console.info('===send success===');
        this.showDatas.push('服务端:' + tcpSendOptions.data)
      })
    }
  }

  build() {
    Column({ space: 5 }) {
      Text('TCP的服务端实现')
        .fontSize(30)

      Row({ space: 5 }) {
        Text('服务端ip:')
          .width(110)
          .fontSize(20)
          .textAlign(TextAlign.End)

        TextInput({ placeholder: this.serverLocalIp })
          .fontSize(20)
          .width('60%')
          .onChange((value) => {
            this.serverLocalIp = value
          })
      }

      Row({ space: 5 }) {
        Text('服务端port:')
          .width(110)
          .fontSize(20)
          .textAlign(TextAlign.End)
        TextInput({ placeholder: this.serverPort.toString() })
          .fontSize(20)
          .width('60%')
          .type(InputType.Number)
          .onChange((value) => {
            this.serverPort = parseInt(value)
          })
      }

      Button('服务端启动并监听连接')
        .fontSize(25)
        .onClick(() => {
          this.listenServer(this.serverLocalIp, this.serverPort)
        })
      TextInput({ placeholder: this.serverData })
        .fontSize(20)
        .width('90%')
        .height(50)
        .onChange((value) => {
          this.serverData = value
        })
      Button('发送消息') //监听连接状态
        .fontSize(25)
        .onClick(()=>{
          this.sendData(this.serverData)
        })

      List(){
        ListItem(){
          Text('服务端消息展示:')
        }
        ForEach(this.showDatas, (item: string) => {
          ListItem(){
            Text(item)
              .fontSize(20)
          }
        })
      }.width('95%')
      .layoutWeight(1)
    }
  }
}

以上代码的UI效果:
在这里插入图片描述

因为需要使用网络,需要开通网络权限:
在这里插入图片描述

本地模拟器模拟TCP服务端的必备操作

IP端口映射

  1. 以管理员身份运行 命令提示符
    在这里插入图片描述

  2. 电脑IP和本地模拟器IP端口映射
    在命令行输入以下代码,其中connectaddress=127.0.0.1 connectport=8000必须一致
    当有服务访问"你电脑的IP:8888"时,操作系统会自动映射到“127.0.0.1:8000

netsh interface portproxy add v4tov4 listenaddress=你的电脑的IP地址 listenport=8888 connectaddress=127.0.0.1 connectport=8000

显示映射结果

netsh interface portproxy show v4tov4

设置端口转发

首先启动本地模拟器
在进行端口转发前,一定要先启动本地模拟器,即 本地模拟器每次重启都需要重新设备端口转发

接下来需要配置鸿蒙模拟器端口转发,使用HDC命令操作,需要用到hdc.exe文件,该文件在OpenHarmony SDK目录下的\toolchains目录内部找到(每个人的路径不同),需要记住该目录。例如我的电脑上hdc.exe的路径:
在这里插入图片描述
进入toolchains目录,在命令行执行以下命令进行端口转发:
注意:本地模拟器每次重启都需要重新进行端口转发

hdc.exe -t 127.0.0.1:5555 fport tcp:8000 tcp:8000

执行以上命令,得到如下结果
在这里插入图片描述
最后将项目部署到模拟器上,启动服务端便可以和TCP客户端连接并且通信了!!!


http://www.kler.cn/a/413164.html

相关文章:

  • C# 泛型(Generic)
  • Airsim安装问题:This project was made with a different version of the Unreal Engine.
  • 排序算法之选择排序篇
  • vue3typescript,shims-vue.d.ts中declare module的vue声明
  • 字节跳动青训营刷题笔记19
  • Uniapp 安装安卓、IOS模拟器并调试
  • python简单算法
  • java全栈day10--后端Web基础(基础知识)
  • Nginx 架构与设计
  • 【计算机网络】多路转接之poll
  • 【rustdesk】客户端和服务端的安装和部署(自建服务器,docker,远程控制开源软件rustdesk)
  • Android开发简单mp4播放器
  • JAVA:Spring Boot 3 实现 Gzip 压缩优化的技术指南
  • 【计算机网络】Wireshark的小测试(Protocol Layers-Wireshark抓包与协议分析实验)
  • 构建Ceph分布式文件共享系统:手动部署指南
  • 在编译Elasticsearch源码时选择Gradle版本
  • 集成 FPGA
  • docker学习的初识
  • Android和Java的发布/订阅事件总线EventBus
  • 决策树——基于乳腺癌数据集与cpu数据集实现
  • 小米PC电脑手机互联互通,小米妙享,小米电脑管家,老款小米笔记本怎么使用,其他品牌笔记本怎么使用,一分钟教会你
  • java语言同时处理多个数据以及计算百分比保留整数
  • 【C++】入门【一】
  • 基于SpringBoot+Vue的汽车票网上预订系统-无偿分享 (附源码+LW+调试)
  • 黑马程序员Java项目实战《苍穹外卖》Day01
  • 【NLP 3、深度学习简介】