鸿蒙开发实战:【网络管理-Socket连接】

news2024/11/30 10:43:38

介绍

本示例主要演示了Socket在网络通信方面的应用,展示了Socket在两端设备的连接验证、聊天通信方面的应用。

效果预览

使用说明

1.打开应用,点击用户文本框选择要登录的用户,并输入另一个设备的IP地址,点击确定按钮进入已登录的用户页面(两个设备都要依次执行此步骤)。

2.在其中一个设备上点击创建房间按钮,任意输入房间号,另一个设备会收到有房间号信息的弹框,点击确定按钮后,两个设备进入聊天页面。

3.在其中一个设备上输入聊天信息并点击发送按钮后,另一个设备的聊天页面会收到该聊天消息。

4.点击顶部标题栏右侧的退出图标按钮,则返回已登录的用户页面。

5.点击聊天页面中的昵称栏,会弹出一个菜单,选择离线选项后,两端设备的状态图标都会切换为离线图标,并且昵称栏都会变成灰色,此时任何一端发送消息另一端都接收不到消息。

6.当点击昵称栏再次切换为在线状态,则两端的己方账号状态会切换为在线图标,同时两端的昵称栏会显示蓝色,此时可正常收发消息。

工程目录

entry/src/main/ets/MainAbility
|---app.ets
|---model
|   |---chatBox.ts                     // 聊天页面
|   |---DataSource.ts                  // 数据获取
|   |---Logger.ts                      // 日志工具
|---pages
|   |---Index.ets                      // 监听消息页面
|   |---Login.ets                      // 首页登录页面
|---Utils
|   |---Utils.ets

具体实现

  • 本示例分为三个模块
    • 输入对端IP模块
      • 使用wifi.getIpInfo()方法获取IP地址,constructUDPSocketInstance方法创建一个UDPSocket对象
      • 源码链接:[Login.ets]
/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import wifi from '@ohos.wifi';
import router from '@ohos.router';
import { resolveIP } from '../Utils/Util'
import socket from '@ohos.net.socket';
import Logger from '../model/Logger'

const TAG: string = '[Login]'

let localAddr = {
  address: resolveIP(wifi.getIpInfo().ipAddress),
  family: 1,
  port: 0
}
let oppositeAddr = {
  address: '',
  family: 1,
  port: 0
}
let loginCount = 0

let udp = socket.constructUDPSocketInstance()

@Entry
@Component
struct Login {
  @State login_feng: boolean = false
  @State login_wen: boolean = false
  @State user: string = ''
  @State roomDialog: boolean = false
  @State confirmDialog: boolean = false
  @State ipDialog: boolean = true
  @State warnDialog: boolean = false
  @State warnText: string = ''
  @State roomNumber: string = ''
  @State receiveMsg: string = ''

  bindOption() {
    let bindOption = udp.bind(localAddr);
    bindOption.then(() => {
      Logger.info(TAG, 'bind success');
    }).catch(err => {
      Logger.info(TAG, 'bind fail');
    })
    udp.on('message', data => {
      Logger.info(TAG, `data:${JSON.stringify(data)}`);
      let buffer = data.message;
      let dataView = new DataView(buffer);
      Logger.info(TAG, `length = ${dataView.byteLength}`);
      let str = '';
      for (let i = 0;i < dataView.byteLength; ++i) {
        let c = String.fromCharCode(dataView.getUint8(i));
        if (c != '') {
          str += c;
        }
      }
      if (str == 'ok') {
        router.clear();
        loginCount += 1;
        router.push({
          url: 'pages/Index',
          params: { address: oppositeAddr.address, port: oppositeAddr.port, loginCount: loginCount }
        })
      }
      else {
        this.receiveMsg = str;
        this.confirmDialog = true;
      }
    })
  }

  build() {
    Stack({ alignContent: Alignment.Center }) {
      Column() {
        Text($r('app.string.MainAbility_label'))
          .width('100%')
          .height(50)
          .backgroundColor('#0D9FFB')
          .textAlign(TextAlign.Start)
          .fontSize(25)
          .padding({ left: 10 })
          .fontColor(Color.White)
          .fontWeight(FontWeight.Bold)
        if (!this.ipDialog) {
          Column() {
            Image(this.login_feng ? $r('app.media.fengziOn') : $r('app.media.wenziOn'))
              .width(100)
              .height(100)
              .objectFit(ImageFit.Fill)
            Text('用户名:' + this.user).fontSize(25).margin({ top: 50 })

            Button() {
              Text($r('app.string.create_room')).fontSize(25).fontColor(Color.White)
            }
            .width('150')
            .height(50)
            .margin({ top: 30 })
            .type(ButtonType.Capsule)
            .onClick(() => {
              this.roomDialog = true
              this.bindOption()
            })
          }.width('90%').margin({ top: 100 })
        }

      }.width('100%').height('100%')

      if (this.confirmDialog) {
        Column() {
          Text('确认码:' + this.receiveMsg).fontSize(25)
          Row() {
            Button($r('app.string.cancel'))
              .onClick(() => {
                this.confirmDialog = false
              }).backgroundColor(0xffffff).fontColor(Color.Black)
            Button($r('app.string.confirm'))
              .onClick(() => {
                udp.send({
                  data: 'ok',
                  address: oppositeAddr
                }).then(function (data) {
                  Logger.info(TAG, `send ${JSON.stringify(data)}`);
                }).catch(function (err) {
                  Logger.info(TAG, `send ${JSON.stringify(err)}`);
                })
                router.clear()
                loginCount += 1;
                router.push({
                  url: 'pages/Index',
                  params: { address: oppositeAddr.address, port: oppositeAddr.port, loginCount: loginCount }
                })
                this.confirmDialog = false;
              }).backgroundColor(0xffffff).fontColor(Color.Red)
          }.margin({ bottom: 10 })
          .justifyContent(FlexAlign.SpaceAround)
        }
        .width('80%')
        .height(150)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
      if (this.ipDialog) {
        Column() {
          Text('本地IP:' + localAddr.address).fontSize(25).margin({ top: 10 })
          Text('用户:' + this.user).fontSize(20).margin({ top: 10 })
            .bindMenu([{
              value: '风子',
              action: () => {
                this.user = '风子'
                this.login_feng = true
                this.login_wen = false
                localAddr.port = 8080
                oppositeAddr.port = 9090
              }
            },
              {
                value: '蚊子',
                action: () => {
                  this.user = '蚊子'
                  this.login_wen = true
                  this.login_feng = false
                  localAddr.port = 9090
                  oppositeAddr.port = 8080
                }
              }
            ])
          TextInput({ placeholder: '请输入对端ip' })
            .width(200)
            .fontSize(25)
            .margin({ top: 10 })
            .onChange((value: string) => {
              oppositeAddr.address = value;
            })

          if (this.warnDialog) {
            Text(this.warnText).fontSize(10).fontColor(Color.Red).margin({ top: 5 })
          }
          Button($r('app.string.confirm'))
            .fontColor(Color.Black)
            .height(30)
            .margin({ bottom: 10 })
            .onClick(() => {
              if (this.user == '') {
                this.warnDialog = true;
                this.warnText = '请先选择用户';
              } else if (oppositeAddr.address === '') {
                this.warnDialog = true;
                this.warnText = '请先输入对端IP';
              } else {
                this.bindOption()
                this.ipDialog = false;
                Logger.debug(TAG, `peer ip=${oppositeAddr.address}`);
                Logger.debug(TAG, `peer port=${oppositeAddr.port}`);
                Logger.debug(TAG, `peer port=${localAddr.port}`);
              }
            })
            .backgroundColor(0xffffff)
        }
        .width('80%')
        .height(200)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
      if (this.roomDialog) {
        Column() {
          Text($r('app.string.input_roomNumber')).fontSize(25).margin({ top: 10 })
          TextInput()
            .width(100)
            .fontSize(25)
            .margin({ top: 10 })
            .onChange((value: string) => {
              this.roomNumber = value;
            })
          Row() {
            Button($r('app.string.cancel'))
              .onClick(() => {
                this.roomDialog = false
              }).backgroundColor(0xffffff).fontColor(Color.Black)
            Button($r('app.string.confirm'))
              .onClick(() => {
                Logger.info(TAG, `[ROOM]address=${oppositeAddr.address}`);
                Logger.info(TAG, `[ROOM]port=${oppositeAddr.port}`);
                /*点击确定后发送房间号,另一端开始监听*/
                Logger.info(TAG, `[ROOM]oppositeAddr.address=${oppositeAddr.address}`);
                Logger.info(TAG, `[ROOM]oppositeAddr.port=${oppositeAddr.port}`);
                Logger.info(TAG, `[ROOM]localAddr.address=${localAddr.address}`);
                Logger.info(TAG, `[ROOM]localAddr.port=${localAddr.port}`);
                this.bindOption()
                udp.send({
                  data: this.roomNumber,
                  address: oppositeAddr
                }).then(function (data) {
                  Logger.info(TAG, `send success, data = ${JSON.stringify(data)}`);
                }).catch(function (err) {
                  Logger.info(TAG, `send fail, err = ${JSON.stringify(err)}`);
                })
                this.roomDialog = false;
              }).backgroundColor(0xffffff).fontColor(Color.Red)
          }.margin({ bottom: 10 })
          .justifyContent(FlexAlign.SpaceAround)
        }
        .width('80%')
        .height(150)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
    }
  }
}

[Util.ets]

/*

* Copyright (c) 2022-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
  */

export function resolveIP(ip) {
if (ip < 0 || ip > 0xFFFFFFFF) {
throw ('The number is not normal!');
}
return (ip >>> 24) + '.' + (ip >> 16 & 0xFF) + '.' + (ip >> 8 & 0xFF) + '.' + (ip & 0xFF);
}
  • 创建房间模块
    • 点击创建房间按钮,弹出创建房间框,输入房间号,点击确定,进入聊天页面
    • 源码链接:[Login.ets]
/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import wifi from '@ohos.wifi';
import router from '@ohos.router';
import { resolveIP } from '../Utils/Util'
import socket from '@ohos.net.socket';
import Logger from '../model/Logger'

const TAG: string = '[Login]'

let localAddr = {
  address: resolveIP(wifi.getIpInfo().ipAddress),
  family: 1,
  port: 0
}
let oppositeAddr = {
  address: '',
  family: 1,
  port: 0
}
let loginCount = 0

let udp = socket.constructUDPSocketInstance()

@Entry
@Component
struct Login {
  @State login_feng: boolean = false
  @State login_wen: boolean = false
  @State user: string = ''
  @State roomDialog: boolean = false
  @State confirmDialog: boolean = false
  @State ipDialog: boolean = true
  @State warnDialog: boolean = false
  @State warnText: string = ''
  @State roomNumber: string = ''
  @State receiveMsg: string = ''

  bindOption() {
    let bindOption = udp.bind(localAddr);
    bindOption.then(() => {
      Logger.info(TAG, 'bind success');
    }).catch(err => {
      Logger.info(TAG, 'bind fail');
    })
    udp.on('message', data => {
      Logger.info(TAG, `data:${JSON.stringify(data)}`);
      let buffer = data.message;
      let dataView = new DataView(buffer);
      Logger.info(TAG, `length = ${dataView.byteLength}`);
      let str = '';
      for (let i = 0;i < dataView.byteLength; ++i) {
        let c = String.fromCharCode(dataView.getUint8(i));
        if (c != '') {
          str += c;
        }
      }
      if (str == 'ok') {
        router.clear();
        loginCount += 1;
        router.push({
          url: 'pages/Index',
          params: { address: oppositeAddr.address, port: oppositeAddr.port, loginCount: loginCount }
        })
      }
      else {
        this.receiveMsg = str;
        this.confirmDialog = true;
      }
    })
  }

  build() {
    Stack({ alignContent: Alignment.Center }) {
      Column() {
        Text($r('app.string.MainAbility_label'))
          .width('100%')
          .height(50)
          .backgroundColor('#0D9FFB')
          .textAlign(TextAlign.Start)
          .fontSize(25)
          .padding({ left: 10 })
          .fontColor(Color.White)
          .fontWeight(FontWeight.Bold)
        if (!this.ipDialog) {
          Column() {
            Image(this.login_feng ? $r('app.media.fengziOn') : $r('app.media.wenziOn'))
              .width(100)
              .height(100)
              .objectFit(ImageFit.Fill)
            Text('用户名:' + this.user).fontSize(25).margin({ top: 50 })

            Button() {
              Text($r('app.string.create_room')).fontSize(25).fontColor(Color.White)
            }
            .width('150')
            .height(50)
            .margin({ top: 30 })
            .type(ButtonType.Capsule)
            .onClick(() => {
              this.roomDialog = true
              this.bindOption()
            })
          }.width('90%').margin({ top: 100 })
        }

      }.width('100%').height('100%')

      if (this.confirmDialog) {
        Column() {
          Text('确认码:' + this.receiveMsg).fontSize(25)
          Row() {
            Button($r('app.string.cancel'))
              .onClick(() => {
                this.confirmDialog = false
              }).backgroundColor(0xffffff).fontColor(Color.Black)
            Button($r('app.string.confirm'))
              .onClick(() => {
                udp.send({
                  data: 'ok',
                  address: oppositeAddr
                }).then(function (data) {
                  Logger.info(TAG, `send ${JSON.stringify(data)}`);
                }).catch(function (err) {
                  Logger.info(TAG, `send ${JSON.stringify(err)}`);
                })
                router.clear()
                loginCount += 1;
                router.push({
                  url: 'pages/Index',
                  params: { address: oppositeAddr.address, port: oppositeAddr.port, loginCount: loginCount }
                })
                this.confirmDialog = false;
              }).backgroundColor(0xffffff).fontColor(Color.Red)
          }.margin({ bottom: 10 })
          .justifyContent(FlexAlign.SpaceAround)
        }
        .width('80%')
        .height(150)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
      if (this.ipDialog) {
        Column() {
          Text('本地IP:' + localAddr.address).fontSize(25).margin({ top: 10 })
          Text('用户:' + this.user).fontSize(20).margin({ top: 10 })
            .bindMenu([{
              value: '风子',
              action: () => {
                this.user = '风子'
                this.login_feng = true
                this.login_wen = false
                localAddr.port = 8080
                oppositeAddr.port = 9090
              }
            },
              {
                value: '蚊子',
                action: () => {
                  this.user = '蚊子'
                  this.login_wen = true
                  this.login_feng = false
                  localAddr.port = 9090
                  oppositeAddr.port = 8080
                }
              }
            ])
          TextInput({ placeholder: '请输入对端ip' })
            .width(200)
            .fontSize(25)
            .margin({ top: 10 })
            .onChange((value: string) => {
              oppositeAddr.address = value;
            })

          if (this.warnDialog) {
            Text(this.warnText).fontSize(10).fontColor(Color.Red).margin({ top: 5 })
          }
          Button($r('app.string.confirm'))
            .fontColor(Color.Black)
            .height(30)
            .margin({ bottom: 10 })
            .onClick(() => {
              if (this.user == '') {
                this.warnDialog = true;
                this.warnText = '请先选择用户';
              } else if (oppositeAddr.address === '') {
                this.warnDialog = true;
                this.warnText = '请先输入对端IP';
              } else {
                this.bindOption()
                this.ipDialog = false;
                Logger.debug(TAG, `peer ip=${oppositeAddr.address}`);
                Logger.debug(TAG, `peer port=${oppositeAddr.port}`);
                Logger.debug(TAG, `peer port=${localAddr.port}`);
              }
            })
            .backgroundColor(0xffffff)
        }
        .width('80%')
        .height(200)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
      if (this.roomDialog) {
        Column() {
          Text($r('app.string.input_roomNumber')).fontSize(25).margin({ top: 10 })
          TextInput()
            .width(100)
            .fontSize(25)
            .margin({ top: 10 })
            .onChange((value: string) => {
              this.roomNumber = value;
            })
          Row() {
            Button($r('app.string.cancel'))
              .onClick(() => {
                this.roomDialog = false
              }).backgroundColor(0xffffff).fontColor(Color.Black)
            Button($r('app.string.confirm'))
              .onClick(() => {
                Logger.info(TAG, `[ROOM]address=${oppositeAddr.address}`);
                Logger.info(TAG, `[ROOM]port=${oppositeAddr.port}`);
                /*点击确定后发送房间号,另一端开始监听*/
                Logger.info(TAG, `[ROOM]oppositeAddr.address=${oppositeAddr.address}`);
                Logger.info(TAG, `[ROOM]oppositeAddr.port=${oppositeAddr.port}`);
                Logger.info(TAG, `[ROOM]localAddr.address=${localAddr.address}`);
                Logger.info(TAG, `[ROOM]localAddr.port=${localAddr.port}`);
                this.bindOption()
                udp.send({
                  data: this.roomNumber,
                  address: oppositeAddr
                }).then(function (data) {
                  Logger.info(TAG, `send success, data = ${JSON.stringify(data)}`);
                }).catch(function (err) {
                  Logger.info(TAG, `send fail, err = ${JSON.stringify(err)}`);
                })
                this.roomDialog = false;
              }).backgroundColor(0xffffff).fontColor(Color.Red)
          }.margin({ bottom: 10 })
          .justifyContent(FlexAlign.SpaceAround)
        }
        .width('80%')
        .height(150)
        .margin({ top: '10%' })
        .backgroundColor(Color.White)
        .border({ radius: 10, width: 3 })
      }
    }
  }
}

[Util.ets]

/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

export function resolveIP(ip) {
  if (ip < 0 || ip > 0xFFFFFFFF) {
    throw ('The number is not normal!');
  }
  return (ip >>> 24) + '.' + (ip >> 16 & 0xFF) + '.' + (ip >> 8 & 0xFF) + '.' + (ip & 0xFF);
}
相关概念

UDP Socket是面向非连接的协议,它不与对方建立连接,而是直接把我要发的数据报发给对方,适用于一次传输数据量很少、对可靠性要求不高的或对实时性要求高的应用场景。

相关权限

1.允许使用Internet网络权限:[ohos.permission.INTERNET]

2.允许应用获取WLAN信息权限:[ohos.permission.GET_WIFI_INFO]

依赖

不涉及。

约束与限制

1.本示例仅支持标准系统上运行,支持设备:RK3568。

2.本示例仅支持API9版本SDK,版本号:3.2.11.9 及以上。

3.本示例需要使用DevEco Studio 3.1 Beta2 (Build Version: 3.1.0.400 构建 2023年4月7日)及以上才可编译运行。

下载

如需单独下载本工程,执行如下命令:

git init
git config core.sparsecheckout true
echo code\BasicFeature\Connectivity\Socket > .git/info/sparse-checkout
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
git pull origin master

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【毛毛讲书】【好运】为什么有些人天生就有好运眷顾?

重磅专栏推荐&#xff1a; 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域&#xff0c;包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用&#xff0c;以及与之相关的人工智能生成内容&#xff…

什么是web组态?Web组态软件哪个好用?

随着工业4.0的到来&#xff0c;物联网、大数据、人工智能等技术的融合应用&#xff0c;使得工业领域正在经历一场深刻的变革。在这个过程中&#xff0c;Web组态技术以其独特的优势&#xff0c;正在逐渐受到越来越多企业的关注和认可。那么&#xff0c;什么是Web组态&#xff1f…

轻巧的elasticsearch可视化工具

一、概述 常见的ES可视化工具有&#xff1a; kibanaelasticsearch-headElasticHDDejavucerebroelasticview 一、安装elasticview 在众多ES可视化龚居中&#xff0c;elasticview是一款比较轻量简洁&#xff0c;兼容性较好&#xff0c;可以兼容多个ES版本&#xff0c;不但可以进…

[蓝桥杯 2020 省 AB3] 限高杆

分层图建图典题 #include<bits/stdc.h> using namespace std; using ll long long; #define int long long const int N 6e510; const int inf 0x3f3f3f3f; const int mod 1e97; int e[N],ne[N],w[N],h[N],idx; void add(int a,int b,int c){e[idx] b,ne[idx] h[a]…

外键约束

目录 外键约束 对数据表进行初期设计&#xff0c;暂时不使用外键 验证限制三 验证级联删除 设置级联更新 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 外键约束 外键约束主要是在父子表关系中体现的一种约束操作。…

【二叉树】算法例题

目录 九、二叉树 68. 二叉树的最大深度 ① 69. 相同的树 ① √ 70. 翻转二叉树 ① 71. 对称二叉树 ① 72. 从前序与中序遍历序列构造二叉树 ② 73. 从中序与后续遍历序列构造二叉树 ② 74. 填充每个节点的下一个右侧节点指针 II ② 75. 二叉树展开为链表 ② 76.…

鸿蒙实战开发:【FaultLoggerd组件】讲解

简介 Faultloggerd部件是OpenHarmony中C/C运行时崩溃临时日志的生成及管理模块。面向基于 Rust 开发的部件&#xff0c;Faultloggerd 提供了Rust Panic故障日志生成能力。系统开发者可以在预设的路径下找到故障日志&#xff0c;定位相关问题。 架构 Native InnerKits 接口 Si…

Marin说PCB之电源完整性之直流压降仿真CST--03

本期内容主要讲解的是关于在CST软件上电源直流压降仿真VRM的一些相关参数设置&#xff0c;小编我在之前文章中有说到过如何利用CST仿真电源信号的直流压降&#xff0c;不过有一些问题我这边再去补充一些。 首先就是VRM芯片的设置了&#xff0c;小编我还是按照之前那样设置&…

腾讯云k8s容器服务

1、新建一个集群 这个网址&#xff1a; 登录登录 - 腾讯云 2、选择第一个 3、名字随便起一个&#xff0c;然后基本默认就行 4、 组件配置直接跳过&#xff0c;信息确认&#xff0c;等待集群初始化&#xff0c;等10分钟左右&#xff08;容器服务需要充点钱才行&#xff09; 5…

学习vue3第八节(自定义指令 directive)

1、自定义指令的作用&#xff1a; 自定义指令是用来操作底层DOM的&#xff0c;尽管vue推崇数据驱动视图的理念&#xff0c;但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和拓展&#xff0c;不仅仅可用于定义任何DOM操作&#xff0c;并且是可以重复使用。 自定义…

杨氏矩阵的查找(复杂度<O(N))

题目&#xff1a; 解释&#xff1a;时间复杂度小于O(N)即不要一个一个的去遍历查找。 思路&#xff1a; 一个33的二维数组如图所示&#xff1a; 一&#xff1a;先找到一个最关键的数字&#xff0c;3&#xff08;下标为0,2&#xff09; 关键数的关键之处在于&#xff08;处于…

过拟合欠拟合

问题&#xff1a;训练数据训练的很好啊&#xff0c;误差也不大&#xff0c;为什么在测试集上面有问题呢&#xff1f; 当算法在某个数据集当中出现这种情况&#xff0c;可能就出现了过拟合现象。 1、 什么是过拟合与欠拟合 欠拟合 过拟合 分析第一种情况&#xff1a;因为机器…

[Python人工智能] 四十三.命名实体识别 (4)利用bert4keras构建Bert+BiLSTM-CRF实体识别模型

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解如何实现中文命名实体识别研究,构建BiGRU-CRF模型实现。这篇文章将继续以中文语料为主,介绍融合Bert的实体识别研究,使用bert4keras和kears包来构建Bert+BiLSTM-CRF模型。然而,该代码最终结…

Linux用户、用户组

用户管理命令&#xff1a; 首先要先知道两个配置文件&#xff1a;/etc/group 用户组配置文件/etc/passwd 保存了所有用户的用于读取的必要信息**/etc/shadow **是 Linux 系统中用于存储用户密码信息的文件。这个文件也被称为“影子文件”&#xff0c;因为它包含了 /etc/passwd…

Unity发布webgl设置占满浏览器运行

Unity发布webgl设置占满浏览器运行 Unity发布webgl的时候index.html的模板文件 模板文件路径&#xff0c;根据自己的需求修改。 C:\Program Files\Unity\Hub\Editor\2021.1.18f1c1\Editor\Data\PlaybackEngines\WebGLSupport\BuildTools\WebGLTemplates\Default再桌面新建一个t…

chatgpt大模型基础学习

chatgpt大模型基础学习 1. 吴恩达提示工程2. 大模型说的token是什么 1. 吴恩达提示工程 知乎 https://zhuanlan.zhihu.com/p/626290417?utm_id0 中文版 https://mp.weixin.qq.com/s?__bizMzkwMjQ5MzExMg&mid2247483714&idx1&sn5e905f5ec6196f6dc2187db2a8618f02&…

Jmeter接口测试,一篇足矣。

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 现在对测试人员的要求越来越高&#xff0c;不仅仅要做好…

使用强森算法求任意两点之间最短路径

对于强森算法的算法思想,如果给定的图中是没有负数的边,那么就可以使用迪杰斯特拉算法来进行遍历每个节点,找到它与其他节点的最短路径,而如果给定的图中是存在负数的边,但是不存在负数的环的时候,那么就可以使用算法对边长做一些修改并且可以准确的找到给定的两个节点之…

各种窗函数对脉压结果的影响

雷达导论专栏总目录链接: 雷达导论专栏总目录-CSDN博客 1. 各类窗函数 有几个窗函数的系数可配,配置如下: tukeywin(N,0.75)kaiser(N,2.5)gausswin(N,1.5)taylorwin(N,3,-24)2. 时域加窗 时域加窗时,直接加在匹配滤波函数上:Htw=exp(1j*pi*K*tp.^2).*win;。那么矩形窗就相…

手撕算法-最长公共子序列(二)

最长公共子序列(二) 分析&#xff1a;典型的动态规划&#xff0c;直接看代码了。 代码&#xff1a; import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** longest common sub…