主頁 >  其他 > go微服務開山篇之protoBuf組件

go微服務開山篇之protoBuf組件

2020-09-21 12:16:42 其他

文章目錄

  • protoBuf安裝
    • 下載安裝
    • proto命令
  • proto語法
    • message型別
      • 定義方式
      • 說明:
      • 欄位定義
        • 欄位詳細說明
      • 注釋
    • enum列舉型別
      • 定義方式
      • 欄位定義
    • service型別
      • 定義方式
      • 欄位定義
    • 使用其他 Message 型別
    • 欄位型別
  • protoBuf組件小實戰
    • proto檔案
    • proto轉go檔案
    • go使用轉換過來的檔案

protoBuf安裝

下載安裝

  1. 下載地址:https://github.com/protocolbuffers/protobuf/releases

    根據系統下載對應的安裝檔案,我現在是win10就下載了protoc-3.13.0-win64.zip

  2. 解壓檔案,如:E:\protoc-3.13.0-win64

  3. 添加環境變數或者將bin目錄下的protoc.exe拷貝到gopath下的bin檔案夾中,不用添加環境變數

    1. 在系統變數中新建:變數名:PROTOBUF_HOME 變數值:E:\protoc-3.13.0-win64
    2. 在系統變數中,編輯path,將前面建的PROTOBUF_HOME下的添加進去%PROTOBUF_HOME%\bin;
    3. cmd中執行protoc --version查看版本,如果可以看到版本號,說明環境變數沒問題
  4. 安裝protoc-gen-go

    1. 下載:go get -u github.com/golang/protobuf/protoc-gen-go
    2. gopath的bin生成protoc-gen-go.exe

proto命令

# 查看版本資訊
protoc --version

# 生成對應語言的檔案: --go_out=.   這是生成golang檔案 .代表當前目錄  hello.proto檔案名
protoc --go_out=. hello.proto
# 或者
protoc hello.proto --go_out=.

proto語法

hello.proto

// 版本
syntax = "proto3";

/*
option設定包名,不設定默認會使用下一行的package后面的作為包名.
不設定會報一個警告:WARNING: Missing 'go_package' option in "hello.proto",
*/
option go_package = ".;hello";
package hello;

// message:一種訊息型別,后面會詳細說明型別
message Hello{
  // optional默認會加可以不寫,寫了生成
  optional string name = 1;
  int32 age = 2;
  string addr = 3;
}

說明:message 表示messages訊息型別,后面跟訊息名稱

message型別

定義方式

// message后面跟訊息名稱
message xxx{
}

說明:

  • .proto檔案中定義多種messages型別如:message、enum 和 service
  • 一個.proto檔案中可以定義多個messages型別,建議一個檔案中不要出現多種型別,會導致依賴性膨脹

欄位定義

message Hello{
  optional string name = 1;
  required int32 age = 2;
  repeated string addr = 3;
}

欄位詳細說明

/*
	optional默認可以不寫,如果寫了生成需要帶--experimental_allow_proto3_optional引數如:protoc --go_out=. hello.proto --experimental_allow_proto3_optional
	string 型別
	stringVal 變數名
	= 1 不是值是,=后面的數字表示欄位編號
*/
optional string stringVal = 1;
1.欄位規則:可以忽略,不用指定,默認為optional
	// optional 可以傳或者不傳值
    optional:欄位可出現 0 次或1次,表示可選,為空可以指定默認值 [default = 10],不然使用語言的默認值
        optional int32 result_per_page = 3 [default = 10];
            字串默認為空字串
            數字默認為0
            bool默認為false
            列舉默認為第一個列出的值,一定要注意列舉的順序,容易有坑
    // required 必須傳值、而且只能傳一次  注意proto3中已經無法使用required                                   
    required:欄位只能也必須出現 1// repeated 可以傳多個值或者不傳值                                        
    repeated:欄位可出現任意多次(包括 0),陣列或串列要使用這種
2.型別:
    int32int64、sint32、sint64、string32-bit ....
3.欄位名稱:
    注意命名規范 
4.=后面的數字表示欄位編號:
    0 ~ 536870911(除去 1900019999 之間的數字,預留的)


關于optional的說明:
對于接收方,如果能夠識別可選欄位就進行相應的處理,如果無法識別,則忽略該欄位,
訊息中的其它欄位正常處理,---因為optional欄位的特性,
很多介面在升級版本中都把后來添加的欄位都統一的設定為optional欄位,
這樣老的版本無需升級程式也可以正常的與新的軟體進行通信,只不過新的欄位無法識別而已,
因為并不是每個節點都需要新的功能,因此可以做到按需升級和平滑過渡

注釋

// 單行注釋
/* */ 多行注釋

enum列舉型別

定義方式

enum EnumAllowingAlias {
  option allow_alias = true; 
  UNKNOWN = 0;
  STARTED = 1;
  RUNNING = 1;
}

你可以通過為不同的列舉常量指定相同的值來定義別名,
為此,你需要將 allow_alias 選項設定為true,否則 protocol 編譯器將在找到別名時生成錯誤訊息,

enum EnumAllowingAlias {
  option allow_alias = true;
  UNKNOWN = 0;
  STARTED = 1;
  RUNNING = 1;
}

enum EnumNotAllowingAlias {
  UNKNOWN = 0;
  STARTED = 1;
}

欄位定義

UNKNOWN = 0;
STARTED = 1;
RUNNING = 1;

都是常量,沒有型別申明

注意:message中可以嵌套enum型別,里層的欄位編號和外層的欄位編號不沖突

service型別

定義方式

service TestService {
    //rpc 服務端對外的函式名(傳入引數)returns(回傳引數)
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

欄位定義

rpc SayHello (HelloRequest) returns (HelloReply) {}
//rpc 服務端對外的函式名   (傳入引數) returns (回傳引數){}

使用其他 Message 型別

message后面的名稱可以在其他的型別中使用,這個時候型別就是指定的型別了

message SearchResponse {
  repeated Result result = 1;   // 這里的型別是下面定的Result型別,包含 Result message的所有
}

message Result {
  required string url = 1;
  optional string title = 2;
  repeated string snippets = 3;
}

欄位型別

.proto說明Go語言C++語言Python語言Java語言
double浮點型別float64doublefloatdouble
float浮點型別float32floatfloatfloat
int32int32int32intint
int64int64int64int/longlong
uint32uint32uint32int/longint
uint64uint64uint64int/longlong
sint32int32int32intint
sint64int64int64int/longlong
fixed32uint32uint32int/longint
fixed64uint64uint64int/longlong
sfixed32int32int32intint
sfixed34int64int64int/longlong
boolboolboolboolboolean
stringstringstringstr/unicodeString
bytes[]bytestringstrByteString

protoBuf組件小實戰

proto檔案

E:\workspace\src\sample\protoBuf_sample\hello.proto

syntax = "proto3";
option go_package = ".;hello";
package hello;

message Hello{
  optional string name = 1;
  int32 age = 2;
  repeated string addr = 3;
}

proto轉go檔案

E:\workspace\src\sample\protoBuf_sample 到這個目錄執行命令

// 因為proto檔案中有設定optional,轉換就需要加--experimental_allow_proto3_optional引數
protoc --go_out=. hello.proto --experimental_allow_proto3_optional

go使用轉換過來的檔案

這是proto檔案生成的
E:\workspace\src\sample\protoBuf_sample\hello.pb.go

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.23.0
// 	protoc        v3.13.0
// source: hello.proto

package hello

import (
	proto "github.com/golang/protobuf/proto"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type Hello struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name *string  `protobuf:"bytes,1,opt,name=name,proto3,oneof" json:"name,omitempty"`
	Age  int32    `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
	Addr []string `protobuf:"bytes,3,rep,name=addr,proto3" json:"addr,omitempty"`
}

func (x *Hello) Reset() {
	*x = Hello{}
	if protoimpl.UnsafeEnabled {
		mi := &file_hello_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Hello) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Hello) ProtoMessage() {}

func (x *Hello) ProtoReflect() protoreflect.Message {
	mi := &file_hello_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Hello.ProtoReflect.Descriptor instead.
func (*Hello) Descriptor() ([]byte, []int) {
	return file_hello_proto_rawDescGZIP(), []int{0}
}

func (x *Hello) GetName() string {
	if x != nil && x.Name != nil {
		return *x.Name
	}
	return ""
}

func (x *Hello) GetAge() int32 {
	if x != nil {
		return x.Age
	}
	return 0
}

func (x *Hello) GetAddr() []string {
	if x != nil {
		return x.Addr
	}
	return nil
}

var File_hello_proto protoreflect.FileDescriptor

var file_hello_proto_rawDesc = []byte{
	0x0a, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x68,
	0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x4f, 0x0a, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x17, 0x0a,
	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e,
	0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
	0x01, 0x28, 0x05, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72,
	0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x42, 0x07, 0x0a, 0x05,
	0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_hello_proto_rawDescOnce sync.Once
	file_hello_proto_rawDescData = file_hello_proto_rawDesc
)

func file_hello_proto_rawDescGZIP() []byte {
	file_hello_proto_rawDescOnce.Do(func() {
		file_hello_proto_rawDescData = protoimpl.X.CompressGZIP(file_hello_proto_rawDescData)
	})
	return file_hello_proto_rawDescData
}

var file_hello_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_hello_proto_goTypes = []interface{}{
	(*Hello)(nil), // 0: hello.Hello
}
var file_hello_proto_depIdxs = []int32{
	0, // [0:0] is the sub-list for method output_type
	0, // [0:0] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_hello_proto_init() }
func file_hello_proto_init() {
	if File_hello_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_hello_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Hello); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	file_hello_proto_msgTypes[0].OneofWrappers = []interface{}{}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_hello_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_hello_proto_goTypes,
		DependencyIndexes: file_hello_proto_depIdxs,
		MessageInfos:      file_hello_proto_msgTypes,
	}.Build()
	File_hello_proto = out.File
	file_hello_proto_rawDesc = nil
	file_hello_proto_goTypes = nil
	file_hello_proto_depIdxs = nil
}

E:\workspace\src\sample\main.go

package main

import (
	"fmt"
	"github.com/golang/protobuf/proto"
	hello "sample/protoBuf_sample"
)

func main() {
	name := "張三"
	data := &hello.Hello{
		// Name *string 這是因為proto中設定optional
		Name: &name,
		Age:  18,
		Addr: []string{"北京", "上海", "廣州"},
	}
	fmt.Println(data)

	// 編碼
	byte_data, _ := proto.Marshal(data)
	//fmt.Println(byte_data)
	fmt.Printf("編碼:%v\n", byte_data)

	var newData hello.Hello
	// 解碼
	proto.Unmarshal(byte_data, &newData)
	fmt.Printf("解碼:%v", newData)

	fmt.Println(newData.Name) //回傳一個地址
	// 獲取值
	fmt.Println(*newData.Name)
	fmt.Println(newData.GetName())

	// 將struct轉換為字串
	fmt.Println(newData.String())

	// Reset()會將struct的所有field的值清零
	//fmt.Println(newData.Reset)
}

/*
name:"張三"  age:18  addr:"北京"  addr:"上海"  addr:"廣州"
編碼:[10 6 229 188 160 228 184 137 16 18 26 6 229 140 151 228 186 172 26 6 228 184 138 230 181 183 26 6 229 185 191 229 183 158]
解碼:{{{} [] [] 0xc00009c780} 0 [] 0xc0000886c0 18 [北京 上海 廣州]}0xc0000886c0
張三
張三
name:"張三"  age:18  addr:"北京"  addr:"上海"  addr:"廣州"
0x5cd390
*/

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/96919.html

標籤:其他

上一篇:安裝go語言開發環境

下一篇:TypeScript入門

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more