自学内容网 自学内容网

鸿蒙开发虚拟网络配置--虚拟机无法访问服务

问题描述

{"code":2300007,"message":"Couldn't connect to server"}

分析
这两个URL地址 'http://127.0.0.1:8000''http://172.23.0.1:8000' 虽然都指向本地运行的服务,但它们实际上在网络层面有着不同的含义和用途。

  1. http://127.0.0.1:8000

    • 这个地址使用的是IPv4地址中的回环地址(Loopback Address),即127.0.0.1
    • 它是一个特殊的IP地址,用于指向本机(本地计算机)。当你尝试访问这个地址时,你的操作系统会理解为你想要连接到本机上的某个服务,而不是网络上的其他计算机。
    • 这种方式常用于测试和开发目的,因为它确保了所有的网络请求都在本地计算机上处理,不会通过网络发送到其他计算机。
  2. http://172.23.0.1:8000

    • 这个地址属于私有IP地址范围(根据RFC 1918,172.16.0.0172.31.255.255 是私有地址空间的一部分)。
    • 虽然它经常用于内部网络(如家庭网络或企业网络中的设备),但它并不直接等同于本机(除非你的计算机恰好被配置了这个IP地址)。
    • 在一些场景下,如使用Docker容器或虚拟机时,这些私有IP地址可能会被分配给容器或虚拟机,以便它们可以在不干扰主机网络的情况下相互通信。
    • 如果你的计算机(或你正在尝试访问的服务)被配置了这个IP地址,那么访问这个地址就会连接到该地址对应的服务上。但是,如果这不是你的计算机的IP地址,尝试访问它可能会导致无法连接或连接到网络上的另一台设备。
  3. 华为虚拟机

    • 华为虚拟机它的回环地址127.0.0.1指向的虚拟机本身,而不是我们本地的计算机,此时虚拟机需要通过我们搭建服务器的计算机的内网私有ip172.23.0.1(示例地址,通过 ifconfig 查看以太网ip)才能访问服务器。

总结

  • 127.0.0.1 是回环地址,总是指向你的本地计算机。
  • 172.23.0.1 是一个私有IP地址,可能指向你的本地网络中的另一台设备,或者在某些情况下(如Docker容器或虚拟机)被分配给你的计算机。如果你不确定这个地址是否指向你的计算机,你需要检查你的网络配置。
  • 鸿蒙开发应用,虚拟机(ECS服务器)访问部署在自己电脑上的服务时务必使用172.23.0.1私有ip地址(避坑)。
    使用示例:
import { DocumentScannerConfig, SaveOption } from '@kit.VisionKit';
import axios, { AxiosResponse } from '@ohos/axios';
import { BusinessError } from '@kit.BasicServicesKit';


const instance = axios.create({
  // baseURL: 'http://127.0.0.1:8000',
  baseURL: 'http://172.23.0.1:8000',
  timeout: 1000,
});

@Entry
@Component
struct StableDiffusion {
  @State prompt: string = 'A cinematic shot of beautiful woman.';
  @State negativePrompt: string = 'blurry, bad, ugly.';
  @State imageWidth: number = 512;
  @State imageHeight: number = 512;
  @State guidanceScale: number = 0.0;
  @State numInferenceSteps: number = 1;
  @State paramsData: object = new Object({
    'prompt': this.prompt,
    'negative_prompt': this.negativePrompt,
    'width': this.imageWidth,
    'height': this.imageHeight,
    'guidance_scale': this.guidanceScale,
    'num_inference_steps': this.numInferenceSteps
  });
  @State imageImage: string | ResourceStr = $r('app.media.icon');

  build() {
    Column() {
      // 标题
      Text('AI绘画')
        .width('100%')
        .height(40)
        .margin({left: 5, top: 0, right: 5, bottom: 5})
        .textAlign(TextAlign.Center)
        .fontSize(20)
        .fontColor(Color.White)
        .backgroundColor('#B2DFEE')
        .borderRadius(5)

      Column({space: 5}) {
        // 参数
        Column({space: 5}){
          Text('prompt')
            .margin({left:10})
            .fontColor(Color.White)
          TextInput({
            text: $$this.prompt,
            placeholder: 'prompt'
          })
            .placeholderColor(Color.Gray)
            .fontSize(14)
            .height(60)
            .margin(2)
            .maxLines(3)
            .border({width: 1, radius: 5, color: '#B2DFEE'})
        }
        .backgroundColor('#B2DFEE')
        .borderRadius(5)
        .alignItems(HorizontalAlign.Start)

        Column({space: 5}) {
          Text('negative_prompt')
            .fontColor(Color.White)
            .margin({ left: 10 })
          TextInput({
            text: $$this.negativePrompt,
            placeholder: 'negative_prompt'
          })
            .placeholderColor(Color.Gray)
            .fontSize(14)
            .height(40)
            .margin(2)
            .maxLines(2)
            .border({width: 1, radius: 5, color: '#B2DFEE'})
        }
        .backgroundColor('#B2DFEE')
        .borderRadius(5)
        .alignItems(HorizontalAlign.Start)

        Row(){
          Column(){
            Row() {
              Text('宽')
                .fontColor(Color.White)
                .margin({ left: 10, right: 10 })
                .width('20%')
              TextInput({ text: this.imageWidth.toFixed(0) })
                .padding(5)
                .width('50%')
                .margin({top: 2})
                .height(25)
                .borderRadius(3)
                .onChange((value: string) => {
                  this.imageWidth = Number(value);
                })
            }
            .width('100%')
            Slider({
              min:0,
              max:2048,
              value: this.imageWidth,
              step: 8
            })
              .onChange((value: number) => {
                this.imageWidth = value;
              })
          }
          .layoutWeight(1)

          Column(){
            Row(){
              Text('高')
                .fontColor(Color.White)
                .margin({left:10, right:10})
                .width('20%')
              TextInput({text: this.imageHeight.toFixed(0)})
                .padding(5)
                .width('50%')
                .margin({top: 2})
                .height(25)
                .borderRadius(3)
                .onChange((value: string) => {
                  this.imageHeight = Number(value);
                })
            }
            .width('100%')
            Slider({
              min:0,
              max:2048,
              value: $$this.imageHeight,
              step: 8
            })
              .onChange((value: number) => {
                this.imageHeight = value;
              })
          }
          .layoutWeight(1)
        }
        .border({width: 1, radius: 5, color: '#B2DFEE'})
        .justifyContent(FlexAlign.Start)
        .backgroundColor('#B2DFEE')
        .borderRadius(5)

        Row(){
          Column(){
            Row(){
              Text('CGF')
                .margin({left:10, right:10})
                .width('20%')
                .fontColor(Color.White)
              TextInput({text: this.guidanceScale.toFixed(2)})
                .padding(5)
                .width('50%')
                .margin({top: 2})
                .height(25)
                .borderRadius(3)
                .onChange((value: string) => {
                  this.guidanceScale = Number(value);
                })
            }
            .width('100%')
            Slider({
              min:0,
              max:20,
              value: $$this.guidanceScale,
              step: 0.01
            })
              .onChange((value: number) => {
                this.guidanceScale = Number(value.toFixed(2));
              })
          }
          .layoutWeight(1)

          Column(){
            Row(){
              Text('Step')
                .margin({left:10, right:10})
                .width('21%')
                .fontColor(Color.White)
              TextInput({text: this.numInferenceSteps.toFixed(0)})
                .padding(5)
                .width('50%')
                .height(25)
                .margin({top: 2})
                .borderRadius(3)
                .onChange((value: string) => {
                  this.numInferenceSteps = Number(value);
                })
            }
            .width('100%')
            Slider({
              min:1,
              max:100,
              value: $$this.numInferenceSteps,
              step: 1
            })
              .onChange((value: number) => {
                this.numInferenceSteps = value;
              })
          }
          .layoutWeight(1)
        }
        .border({width: 1, radius: 5, color: '#B2DFEE'})
        .justifyContent(FlexAlign.Start)
        .backgroundColor('#B2DFEE')
        .borderRadius(5)

        // 提交按钮
        Button('提交')
          .width(200)
          .buttonStyle(ButtonStyleMode.NORMAL)
          .fontColor(Color.White)
          .backgroundColor('#8DB6CD')
          .onClick(() => {
            this.paramsData = new Object({
              'prompt': this.prompt,
              'negative_prompt': this.negativePrompt,
              'width': this.imageWidth,
              'height': this.imageHeight,
              'guidance_scale': this.guidanceScale,
              'num_inference_steps': this.numInferenceSteps
            });

            console.log('post params: ', JSON.stringify(this.paramsData));

            try {
              // 发送post请求
              instance.post('/api/images/generate', this.paramsData)
                .then((response: AxiosResponse) => {
                  console.log('Response:', response.status);
                  console.log('Response:', response.headers);
                  console.log('Response:', response.data);
                  console.log('Response:', JSON.stringify(response.data));
                  console.log('Response:', response.data.image);

                  // 获取bsae64格式图片
                  this.imageImage = response.data.image;
                },  (err: BusinessError) => {
                  console.error('post请求失败,', err);
                });
            } catch(error) {
              console.log('post请求失败,', error);
            }
          })
      }
      .width('100%')
      .height('50%')

      Divider()
        .vertical(false)
        .color(Color.White)
        .width('100%')
        .strokeWidth(2)
        .margin({bottom: 5})

      // 输出结果图片
      Image(this.imageImage)
        .width('100%')
        .objectFit(ImageFit.Contain)
        .margin(10)
        .draggable(true)
        .borderRadius(5)
        .backgroundColor(Color.Orange)
        .interpolation(ImageInterpolation.High)
        .stateStyles({
          normal:
          {
            .rotate({angle:0})
            .scale({x:1, y: 1})

          },
          pressed:{
            .rotate({angle:0})
            .scale({x: 2, y: 2})
          }
        })
        .animation({
          duration:500
        })
        .draggable(true)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#eee')
    .borderRadius(10)
    .border({
      color: Color.Pink,
      width: 4
    })
  }
}

原文地址:https://blog.csdn.net/weixin_47695827/article/details/140520154

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!