初探grpc-web(服务端go)_grpcwebproxy-程序员宅基地

技术标签: grpc-web  node.js  javascript  

从 https://github.com/improbable-eng/grpc-web/releases/tag/v0.13.0 按操作系统选择下载,如:grpcwebproxy-v0.13.0-win64.exe.zip 。

下载完成后把 grpcwebproxy.exe 放到自建的文件夹,并添加到环境变量的path中。

使用grpcwebproxy代理服务,命令为:
示例:grpcwebproxy --allow_all_origins --backend_addr=localhost:50051 --run_tls_server=false --server_http_debug_port=5005
本地实际为:
grpcwebproxy --allow_all_origins --backend_addr=192.168.1.103:8090 --run_tls_server=false --server_http_debug_port=5005

其中用到的参数说明:
在这里插入图片描述
使用命令把当前文件夹下面所有的.proto文件转成XXX_pb.js和XXX_grpc_web_pb.js,命令为:
protoc --js_out=import_style=commonjs:. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. ./*.proto

hello.proto 文件内容为:

syntax = "proto3";

package hello;

option go_package=".;hello";

// 请求参数
message HelloRequest {
    
    string name = 1;
}

// 响应消息
message HelloInfo {
    
    string hello_data = 1;
}

//服务定义
service HelloService {
    
    rpc Hello (HelloRequest) returns (HelloInfo);
}

转成 XXX_pb.js和XXX_grpc_web_pb.js:

  1. hello_grpc_web_pb.js:
/**
 * @fileoverview gRPC-Web generated client stub for hello
 * @enhanceable
 * @public
 */

// GENERATED CODE -- DO NOT EDIT!


/* eslint-disable */
// @ts-nocheck



const grpc = {
    };
grpc.web = require('grpc-web');

const proto = {
    };
proto.hello = require('./hello_pb.js');

/**
 * @param {string} hostname
 * @param {?Object} credentials
 * @param {?Object} options
 * @constructor
 * @struct
 * @final
 */
proto.hello.HelloServiceClient =
    function(hostname, credentials, options) {
    
  if (!options) options = {
    };
  options['format'] = 'text';

  /**
   * @private @const {!grpc.web.GrpcWebClientBase} The client
   */
  this.client_ = new grpc.web.GrpcWebClientBase(options);

  /**
   * @private @const {string} The hostname
   */
  this.hostname_ = hostname;

};


/**
 * @param {string} hostname
 * @param {?Object} credentials
 * @param {?Object} options
 * @constructor
 * @struct
 * @final
 */
proto.hello.HelloServicePromiseClient =
    function(hostname, credentials, options) {
    
  if (!options) options = {
    };
  options['format'] = 'text';

  /**
   * @private @const {!grpc.web.GrpcWebClientBase} The client
   */
  this.client_ = new grpc.web.GrpcWebClientBase(options);

  /**
   * @private @const {string} The hostname
   */
  this.hostname_ = hostname;

};


/**
 * @const
 * @type {!grpc.web.MethodDescriptor<
 *   !proto.hello.HelloRequest,
 *   !proto.hello.HelloInfo>}
 */
const methodDescriptor_HelloService_Hello = new grpc.web.MethodDescriptor(
  '/hello.HelloService/Hello',
  grpc.web.MethodType.UNARY,
  proto.hello.HelloRequest,
  proto.hello.HelloInfo,
  /**
   * @param {!proto.hello.HelloRequest} request
   * @return {!Uint8Array}
   */
  function(request) {
    
    return request.serializeBinary();
  },
  proto.hello.HelloInfo.deserializeBinary
);


/**
 * @const
 * @type {!grpc.web.AbstractClientBase.MethodInfo<
 *   !proto.hello.HelloRequest,
 *   !proto.hello.HelloInfo>}
 */
const methodInfo_HelloService_Hello = new grpc.web.AbstractClientBase.MethodInfo(
  proto.hello.HelloInfo,
  /**
   * @param {!proto.hello.HelloRequest} request
   * @return {!Uint8Array}
   */
  function(request) {
    
    return request.serializeBinary();
  },
  proto.hello.HelloInfo.deserializeBinary
);


/**
 * @param {!proto.hello.HelloRequest} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @param {function(?grpc.web.Error, ?proto.hello.HelloInfo)}
 *     callback The callback function(error, response)
 * @return {!grpc.web.ClientReadableStream<!proto.hello.HelloInfo>|undefined}
 *     The XHR Node Readable Stream
 */
proto.hello.HelloServiceClient.prototype.hello =
    function(request, metadata, callback) {
    
  return this.client_.rpcCall(this.hostname_ +
      '/hello.HelloService/Hello',
      request,
      metadata || {
    },
      methodDescriptor_HelloService_Hello,
      callback);
};


/**
 * @param {!proto.hello.HelloRequest} request The
 *     request proto
 * @param {?Object<string, string>} metadata User defined
 *     call metadata
 * @return {!Promise<!proto.hello.HelloInfo>}
 *     Promise that resolves to the response
 */
proto.hello.HelloServicePromiseClient.prototype.hello =
    function(request, metadata) {
    
  return this.client_.unaryCall(this.hostname_ +
      '/hello.HelloService/Hello',
      request,
      metadata || {
    },
      methodDescriptor_HelloService_Hello);
};


module.exports = proto.hello;


  1. hello_pb.js:
// source: hello.proto
/**
 * @fileoverview
 * @enhanceable
 * @suppress {missingRequire} reports error on implicit type usages.
 * @suppress {messageConventions} JS Compiler reports an error if a variable or
 *     field starts with 'MSG_' and isn't a translatable message.
 * @public
 */
// GENERATED CODE -- DO NOT EDIT!
/* eslint-disable */
// @ts-nocheck

var jspb = require('google-protobuf');
var goog = jspb;
var global = Function('return this')();

goog.exportSymbol('proto.hello.HelloInfo', null, global);
goog.exportSymbol('proto.hello.HelloRequest', null, global);
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.hello.HelloRequest = function(opt_data) {
    
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.hello.HelloRequest, jspb.Message);
if (goog.DEBUG && !COMPILED) {
    
  /**
   * @public
   * @override
   */
  proto.hello.HelloRequest.displayName = 'proto.hello.HelloRequest';
}
/**
 * Generated by JsPbCodeGenerator.
 * @param {Array=} opt_data Optional initial data array, typically from a
 * server response, or constructed directly in Javascript. The array is used
 * in place and becomes part of the constructed object. It is not cloned.
 * If no data is provided, the constructed object will be empty, but still
 * valid.
 * @extends {jspb.Message}
 * @constructor
 */
proto.hello.HelloInfo = function(opt_data) {
    
  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.hello.HelloInfo, jspb.Message);
if (goog.DEBUG && !COMPILED) {
    
  /**
   * @public
   * @override
   */
  proto.hello.HelloInfo.displayName = 'proto.hello.HelloInfo';
}



if (jspb.Message.GENERATE_TO_OBJECT) {
    
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.hello.HelloRequest.prototype.toObject = function(opt_includeInstance) {
    
  return proto.hello.HelloRequest.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.hello.HelloRequest} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.hello.HelloRequest.toObject = function(includeInstance, msg) {
    
  var f, obj = {
    
    name: jspb.Message.getFieldWithDefault(msg, 1, "")
  };

  if (includeInstance) {
    
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.hello.HelloRequest}
 */
proto.hello.HelloRequest.deserializeBinary = function(bytes) {
    
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.hello.HelloRequest;
  return proto.hello.HelloRequest.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.hello.HelloRequest} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.hello.HelloRequest}
 */
proto.hello.HelloRequest.deserializeBinaryFromReader = function(msg, reader) {
    
  while (reader.nextField()) {
    
    if (reader.isEndGroup()) {
    
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.setName(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.hello.HelloRequest.prototype.serializeBinary = function() {
    
  var writer = new jspb.BinaryWriter();
  proto.hello.HelloRequest.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.hello.HelloRequest} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.hello.HelloRequest.serializeBinaryToWriter = function(message, writer) {
    
  var f = undefined;
  f = message.getName();
  if (f.length > 0) {
    
    writer.writeString(
      1,
      f
    );
  }
};


/**
 * optional string name = 1;
 * @return {string}
 */
proto.hello.HelloRequest.prototype.getName = function() {
    
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};


/**
 * @param {string} value
 * @return {!proto.hello.HelloRequest} returns this
 */
proto.hello.HelloRequest.prototype.setName = function(value) {
    
  return jspb.Message.setProto3StringField(this, 1, value);
};





if (jspb.Message.GENERATE_TO_OBJECT) {
    
/**
 * Creates an object representation of this proto.
 * Field names that are reserved in JavaScript and will be renamed to pb_name.
 * Optional fields that are not set will be set to undefined.
 * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
 * For the list of reserved names please see:
 *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
 * @param {boolean=} opt_includeInstance Deprecated. whether to include the
 *     JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @return {!Object}
 */
proto.hello.HelloInfo.prototype.toObject = function(opt_includeInstance) {
    
  return proto.hello.HelloInfo.toObject(opt_includeInstance, this);
};


/**
 * Static version of the {@see toObject} method.
 * @param {boolean|undefined} includeInstance Deprecated. Whether to include
 *     the JSPB instance for transitional soy proto support:
 *     http://goto/soy-param-migration
 * @param {!proto.hello.HelloInfo} msg The msg instance to transform.
 * @return {!Object}
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.hello.HelloInfo.toObject = function(includeInstance, msg) {
    
  var f, obj = {
    
    helloData: jspb.Message.getFieldWithDefault(msg, 1, "")
  };

  if (includeInstance) {
    
    obj.$jspbMessageInstance = msg;
  }
  return obj;
};
}


/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.hello.HelloInfo}
 */
proto.hello.HelloInfo.deserializeBinary = function(bytes) {
    
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.hello.HelloInfo;
  return proto.hello.HelloInfo.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.hello.HelloInfo} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.hello.HelloInfo}
 */
proto.hello.HelloInfo.deserializeBinaryFromReader = function(msg, reader) {
    
  while (reader.nextField()) {
    
    if (reader.isEndGroup()) {
    
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    
    case 1:
      var value = /** @type {string} */ (reader.readString());
      msg.setHelloData(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};


/**
 * Serializes the message to binary data (in protobuf wire format).
 * @return {!Uint8Array}
 */
proto.hello.HelloInfo.prototype.serializeBinary = function() {
    
  var writer = new jspb.BinaryWriter();
  proto.hello.HelloInfo.serializeBinaryToWriter(this, writer);
  return writer.getResultBuffer();
};


/**
 * Serializes the given message to binary data (in protobuf wire
 * format), writing to the given BinaryWriter.
 * @param {!proto.hello.HelloInfo} message
 * @param {!jspb.BinaryWriter} writer
 * @suppress {unusedLocalVariables} f is only used for nested messages
 */
proto.hello.HelloInfo.serializeBinaryToWriter = function(message, writer) {
    
  var f = undefined;
  f = message.getHelloData();
  if (f.length > 0) {
    
    writer.writeString(
      1,
      f
    );
  }
};


/**
 * optional string hello_data = 1;
 * @return {string}
 */
proto.hello.HelloInfo.prototype.getHelloData = function() {
    
  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};


/**
 * @param {string} value
 * @return {!proto.hello.HelloInfo} returns this
 */
proto.hello.HelloInfo.prototype.setHelloData = function(value) {
    
  return jspb.Message.setProto3StringField(this, 1, value);
};


goog.object.extend(exports, proto.hello);

编写client.js(只先执行一个hello方法):

var {
    
  HelloServiceClient
} =require('./hello_grpc_web_pb');

var {
     HelloRequest } =require('./hello_pb');

let client = new HelloServiceClient('http://localhost:5005');

let helloRequest = new HelloRequest();
helloRequest.setName('tom');

client.hello(helloRequest, {
    }, (err, response) => {
    
  console.log(err, response);
});

打包client.js放到dist/main.js并在index.html头部引入:
npx webpack client.js

运行index.html:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
go写的服务端:

package main

import (
	"context"
	"fmt"
	"golang-grpc-demo/hello"
	"net"

	"google.golang.org/grpc"
)

// HelloServerImpl 定义hello接口实现
type HelloServerImpl struct {
    
	hello.UnimplementedHelloServiceServer
}

// Hello 定义hello的rpc方法
func (h *HelloServerImpl) Hello(ctx context.Context, request *hello.HelloRequest) (*hello.HelloInfo, error) {
    
	name := request.GetName()
	fmt.Println(name)
	return &hello.HelloInfo{
    HelloData: "hello " + name}, nil
}

func main() {
    
	lis, err := net.Listen("tcp", ":8090")
	if err != nil {
    
		fmt.Println(err)
	}
	server := grpc.NewServer()
	hello.RegisterHelloServiceServer(server, &HelloServerImpl{
    })

	if err := server.Serve(lis); err != nil {
    
		fmt.Println(err)
	}
}

使用这个:
在这里插入图片描述

也可以监听:
在这里插入图片描述
在这里插入图片描述

再写一个clientold.js(去执行sayRepeatHello方法):

var {
    
  GreeterClient
} =require('./helloworld_grpc_web_pb');

var {
     HelloRequest,RepeatHelloRequest } =require('./helloworld_pb');

let client = new GreeterClient('http://localhost:5005');

let helloRequest = new HelloRequest();
helloRequest.setName('kitty');
// helloRequest.setCity('合肥');

client.sayHello(helloRequest, {
    }, (err, response) => {
    
  console.log(err, 22,response,response.array);
});

// client.sayRepeatHello(repeatHelloRequest, {});
// server streaming call
var streamRequest = new RepeatHelloRequest();
streamRequest.setName('World');
streamRequest.setCount(7);

var stream = client.sayRepeatHello(streamRequest, {
    });
stream.on('data', (response) => {
    
  console.log(response.getMessage());
});
stream.on('error', (err) => {
    
  console.log(`Unexpected stream error: code = ${
    err.code}` +
              `, message = "${err.message}"`);
});

在这里插入图片描述
服务端go代码:

package main

import (
	"context"
	"fmt"
	"golang-grpc-demo/hello"
	"net"
	"strconv"

	"google.golang.org/grpc"
)

// HelloServerImpl 定义hello接口实现
type HelloServerImpl struct {
    
	hello.UnimplementedGreeterServer
}

// SayHello 定义hello的rpc方法
func (h *HelloServerImpl) SayHello(ctx context.Context, request *hello.HelloRequest) (*hello.HelloReply, error) {
    
	name := request.GetName()
	fmt.Println("SayHello方法接收到请求参数:", name)
	return &hello.HelloReply{
    Message: "SayHello: " + name}, nil
}

// SayRepeatHello 定义hello的rpc方法
func (h *HelloServerImpl) SayRepeatHello(request *hello.RepeatHelloRequest, stream hello.Greeter_SayRepeatHelloServer) error {
    
	name := request.GetName()
	count := request.GetCount()
	fmt.Println("SayRepeatHello方法接收到请求参数:", name, count)
	for i := 0; i < int(count); i++ {
    
		stream.Send(&hello.HelloReply{
    Message: "Count:" + strconv.Itoa(i) + " SayHello: " + name + "\n"})
	}
	return nil
}

func main() {
    
	lis, err := net.Listen("tcp", ":8090")
	if err != nil {
    
		fmt.Println(err)
	}
	server := grpc.NewServer()
	hello.RegisterGreeterServer(server, new(HelloServerImpl))

	if err := server.Serve(lis); err != nil {
    
		fmt.Println(err)
	}
}

要求的类型:
在这里插入图片描述

测试一下,故意写一个字符串类型的次数:
在这里插入图片描述
结果可见:控制台报错了,请求并没有发到服务端:

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43437334/article/details/114502010

智能推荐

2014年高级计算机操作员工种代码36-323不可积分入户深圳吗,计算机操作员 (2011年深圳招调工热门工种)...-程序员宅基地

文章浏览阅读198次。好消息:计算机操作员(工种代码:46-207)被确定为2011年深圳市职业技能鉴定计算机类鉴定工种学习对象:Office2003综合应用:1、向有一定电脑基础,特别是对OFFICE办公软件有一定了解,欲从事计算机日常办公的人员进行培训.2、此科目是深圳市招调工种.图形图像处理CorelDraw X3:1、从事或有意从事工艺美术、广告艺术、图文排版、图文印刷、计算机多媒体技术工作人员以及其他需要掌握..._计算机操作员职业代码

文心一言api接入如何在你的项目里使用文心一言_文言一心api-程序员宅基地

文章浏览阅读7.5k次,点赞6次,收藏47次。基于百度文心一言语言大模型的智能文本对话AI机器人API,支持聊天对话、行业咨询、语言学习、代码编写等功能.您的AppKey和uid是重要信息,请务必妥善保存,避免泄漏!您的AppKey和uid是重要信息,请务必妥善保存,避免泄漏!您的AppKey和uid是重要信息,请务必妥善保存,避免泄漏!AppKey申请通过后,登录。请求方式: POST。_文言一心api

别再用硬编码写业务流程了,试试这款轻量级流程编排框架-程序员宅基地

文章浏览阅读488次。前言在每个公司的系统中,总有一些拥有复杂业务逻辑的系统,这些系统承载着核心业务逻辑,几乎每个需求都和这些核心业务有关,这些核心业务业务逻辑冗长,涉及内部逻辑运算,缓存操作,持久化操作,外部..._什么业务场景要用到编排工具

P1015 回文数_1、若一个5位数字从左向右读与从右向左读都一样,我们就将其称之为回文串。小申编-程序员宅基地

文章浏览阅读297次。题目描述若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。例如:给定一个十进制数5656,将5656加6565(即把5656从右向左读),得到121121是一个回文数。又如:对于十进制数8787:STEP1:8787+7878=165165STEP2:165165+561561=726726STEP3:726726+627627=13531..._1、若一个5位数字从左向右读与从右向左读都一样,我们就将其称之为回文串。小申编

直线与球体的交点lisp_晓东CAD家园-论坛-A/VLISP-[LISP函数]:计算直线与曲线交点-:5 如何用Lisp程序计算支线Line与曲线(二次样条或PLINE拟合曲线)三交点,请诸位高手提...-程序员宅基地

文章浏览阅读389次。[font=courier new]86. xdrx_getinters功能:1.求两个AcDbCurve(曲线)实体的交点.2.求一个AcDbCurve(曲线)实体和一个选择集中所有AcDbCurve(曲线)的交点。3.求一个选择集中所有AcDbCurve(曲线)实体的交点.4.求一个选择集SS1中的所有AcDbCurve实体和另个选择集SS2所有AcDbCurve实体的交点。调用格式: 1. ..._lisp inters

HDU 1198 - Farm Irrigation-程序员宅基地

文章浏览阅读44次。Problem DescriptionBenny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has...

随便推点

Axis2/c 知识点-程序员宅基地

文章浏览阅读145次。官网文档: http://axis.apache.org/axis2/c/core/docs/axis2c_manual.html从文档中可以总结出:1. Axis2/C是一个用C语言实现的Web Service引擎。Axis2/C基于Axis2架构,支持SOAP1.1和SOAP1.2协议,并且支持RESTful风格的Web Service。基于Axis2/C的Web Service可以..._axis2/c服务端调用axis2_get_instance

企业架构方法论-程序员宅基地

文章浏览阅读3k次。目前主要的两种架构方法(准确的说是方法论),具体的方法也是有的,也有可实际操作层面的东西,那要看很多的各个细分专业层面的东西。比如画流程图,业务流程图、数据流程图、系统交互流程图等等。togafzachmanzachman业务建模分析框架,相比于togaf,直观上直接提供了可操作的东西,可能大家更容易接受一些。这里推荐一个架构设计的专业工具,是免费的,即ArchMateArchi – Open Source ArchiMate Modelling (archim..._企业架构方法论

堆栈与队列的方法区分、优先队列的应用_判断是栈还是队列还是优先队列-程序员宅基地

文章浏览阅读123次。堆栈与队列具体的方法区分_判断是栈还是队列还是优先队列

上海计算机学会2021年7月月赛C++丙组T1布置会场-程序员宅基地

文章浏览阅读352次,点赞8次,收藏8次。小爱老师可以购买两份双拼花束后,将他重新组合成一束百合花+一束郁金香。已知布置会场需要用到x束百合花与y束郁金香,请问小爱老师购买花朵最少花费需多少元?输出共一行,一个正整数,表示小爱老师购买花朵最少花费需多少元。直接购买8束百合+6束郁金香,共计8*8+6*10=124元。内存限制: 256 Mb时间限制: 1000 ms。先购买12束双拼花朵,花费12*8=96元,第一行:两个正整数表示需要的花束数量x,y。第二行:三个正整数表示花束费用a,b,c。再购买2束百合花,花费2*8=16元,

python实现ping某一ip_使用Python测试Ping主机IP和某端口是否开放的实例-程序员宅基地

文章浏览阅读518次。使用Python方法比用各种命令方便,可以设置超时时间,到底通不通,端口是否开放一眼能看出来。命令和返回完整权限,可以ping通,端口开放,结果如下:无root权限(省略了ping),端口开放,结果如下:完整权限,可以ping通,远端端口关闭,结果如下:完整权限,可以ping通,本地端口关闭,结果如下:完整权限,不能ping通(端口自然也无法访问),结果如下:pnp.py代码#!/usr/bin/..._python ping ip无管理员权限

zplane函数怎么用m文件调用_matlab中cla用法-程序员宅基地

文章浏览阅读738次。零极点与系统稳定性的关系 4.状态方程含义 5.使用 zplane 函数 [实验原理] 该实验用 MATLAB 中库函数,如 tf2zp(b,a),ss2zp(A,B,C,D),zplane(z,p),......MATLAB 中相关命令 aa abs 绝对值、模、字符的 ascii 码值 a...零极点与系统稳定性的关系 4.状态方程含义 5.使用 zplane 函数 [实验原理] 该实验用 M..._matlabcla。m文件