【gRPC学习】使用go学习gRPC
个人博客:Sekyoro的博客小屋
个人网站:Proanimer的个人网站
RPC是远程调用,而google实现了grpc比较方便地实现了远程调用,gRPC是一个现代的开源远程过程调用(RPC)框架
概念介绍
在gRPC中,客户端应用程序可以直接调用另一台计算机上的服务器应用程序上的方法,就好像它是本地对象一样。
远程过程调用是一个分布式计算的客户端-服务器(Client/Server)的例子,它简单而又广受欢迎。
远程过程调用总是由客户端对服务器发出一个执行若干过程请求,并用客户端提供的参数。执行结果将返回给客户端。
由于存在各式各样的变体和细节差异,对应地派生了各式远程过程调用协议,而且它们并不互相兼容。为了允许不同的客户端均能访问服务器,许多标准化的 RPC 系统应运而生了。其中大部分采用接口描述语言(Interface Description Language,IDL),方便跨平台的远程过程调用。
与许多RPC系统一样,gRPC基于定义服务的思想,指定可以通过其参数和返回类型远程调用的方法。在服务器端,服务器实现了这个接口,并运行gRPC服务器来处理客户端调用。在客户端,客户端有一个stub(在某些语言中称为客户端),它提供与服务器相同的方法。
它具有许多特性
- 强大的IDL特性
RPC使用ProtoBuf来定义服务,ProtoBuf是由Google开发的一种数据序列化协议,性能出众,得到了广泛的应用。 - 支持多种语言
支持C++、Java、Go、Python、Ruby、C#、Node.js、Android Java、Objective-C、PHP等编程语言。 - 基于HTTP/2标准设计
默认情况下,gRPC使用Protocol Buffers,这是谷歌成熟的开源机制,用于序列化结构化数据(尽管它可以与JSON等其他数据格式一起使用)
与REST差异
RPC 的消息传输可以通过 TCP、UDP 或者 HTTP等,所以有时候我们称之为 RPC over TCP、 RPC over HTTP。
RPC 通过 HTTP 传输消息的时候和 RESTful的架构是类似的,但是也有不同。
- gRPC使用HTTP/2,而REST使用HTTP1.1
- gRPC使用协议缓冲区数据格式,而不是REST API中通常使用的标准JSON数据格式
- 使用gRPC,可以利用HTTP/2功能,如服务器端流式传输、客户端流式传输,甚至双向流式传输
首先 RPC 的客户端和服务器端师紧耦合的,客户端需要知道调用的过程的名字,过程的参数以及它们的类型、顺序等。一旦服务器更改了过程的实现,客户端的实现很容易出问题。RESTful基于 http的语义操作资源,参数的顺序一般没有关系,也很容易的通过代理转换链接和资源位置,从这一点上来说,RESTful 更灵活。
其次,它们操作的对象不一样。 RPC 操作的是方法和过程,它要操作的是方法对象。 RESTful 操作的是资源(resource),而不是方法。
第三,RESTful执行的是对资源的操作,增加、查找、修改和删除等,主要是CURD,所以如果你要实现一个特定目的的操作,比如为名字姓张的学生的数学成绩都加上10这样的操作,
RESTful的API设计起来就不是那么直观或者有意义。在这种情况下, RPC的实现更有意义,它可以实现一个直接的方法方法供客户端调用
RPC over TCP可以通过长连接减少连接的建立所产生的花费,在调用次数非常巨大的时候(这是目前互联网公司经常遇到的情况,大并发的情况下),这个花费影响是非常巨大的。
当然 RESTful 也可以通过 keep-alive 实现长连接, 但是它最大的一个问题是它的request-response模型是阻塞的 (http1.0和 http1.1, http 2.0没这个问题),
发送一个请求后只有等到response返回才能发送第二个请求 (有些http server实现了pipeling的功能,但不是标配), RPC的实现没有这个限制。
其他RPC框架
目前的 RPC 框架大致有两种不同的侧重方向,一种偏重于服务治理,另一种偏重于跨语言调用。
服务治理型的 RPC 框架有Alibabs Dubbo、Motan 等,这类的 RPC 框架的特点是功能丰富,提供高性能的远程调用以及服务发现和治理功能,适用于大型服务的微服务化拆分以及管理,对于特定语言(Java)的项目可以十分友好的透明化接入。但缺点是语言耦合度较高,跨语言支持难度较大。
跨语言调用型的 RPC 框架有 Thrift、gRPC、Hessian、Finagle 等,这一类的 RPC 框架重点关注于服务的跨语言调用,能够支持大部分的语言进行语言无关的调用,非常适合于为不同语言提供通用远程服务的场景。但这类框架没有服务发现相关机制,实际使用时一般需要代理层进行请求转发和负载均衡策略控制。
thrift是Apache的一个跨语言的高性能的服务框架,也得到了广泛的应用。它的功能类似 gRPC, 支持跨语言,不支持服务治理。
rpcx 是一个分布式的Go语言的 RPC 框架,支持Zookepper、etcd、consul多种服务发现方式,多种服务路由方式, 是目前性能最好的 RPC 框架之一
使用protobuf
定义要在proto文件中序列化的数据的结构:这是一个扩展名为.proto的普通文本文件。协议缓冲区数据被构造为消息,其中每个消息都是一个包含一系列名值对(称为字段)的信息的小逻辑记录。
message Person {string name = 1;int32 id = 2;bool has_ponycopter = 3;
}
指定了数据结构,就可以使用协议缓冲区编译器protoc从proto定义中生成首选语言的数据访问类.
它们为每个字段提供了简单的访问器,如name()和set_name(),以及将整个结构序列化到原始字节/从原始字节解析整个结构的方法。
因此,例如,如果选择的语言是C++,那么在上面的示例中运行编译器将生成一个名为Person的类。然后,您可以在应用程序中使用此类来填充、序列化和检索Person协议缓冲区消息。
gRPC使用protoc和一个特殊的gRPC插件从proto文件中生成代码:可以获得生成的gRPC客户端和服务器代码,以及用于填充、序列化和检索消息类型的常规协议缓冲区代码。(截至目前protobuf最新版本是v3)
gRPC in Go
下载protoc
虽然不是强制性的,但gRPC应用程序通常利用proto buffer进行服务定义和数据序列化。
Releases · protocolbuffers/protobuf (github.com)
protoc用于编译.proto文件,其中包含服务和消息定义,Linux或Mac直接使用对应包管理器下载即可
apt install -y protobuf-compiler
protoc --version # Ensure compiler version is 3+
Windows在github上下载二进制包Releases · protocolbuffers/protobuf (github.com)
protocol compiler的Go插件
下载protoc-go-gen
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
下载zip的文件
git clone -b v1.60.1 --depth 1 https://github.com/grpc/grpc-go
proto文件
下面定义了服务
// Interface exported by the server.
service RouteGuide {// A simple RPC.//// Obtains the feature at a given position.//// A feature with an empty name is returned if there's no feature at the given// position.rpc GetFeature(Point) returns (Feature) {}// A server-to-client streaming RPC.//// Obtains the Features available within the given Rectangle. Results are// streamed rather than returned at once (e.g. in a response message with a// repeated field), as the rectangle may cover a large area and contain a// huge number of features.rpc ListFeatures(Rectangle) returns (stream Feature) {}// A client-to-server streaming RPC.//// Accepts a stream of Points on a route being traversed, returning a// RouteSummary when traversal is completed.rpc RecordRoute(stream Point) returns (RouteSummary) {}// A Bidirectional streaming RPC.//// Accepts a stream of RouteNotes sent while a route is being traversed,// while receiving other RouteNotes (e.g. from other users).rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}
其中涉及到一些参数message表示传递数据.
// Points are represented as latitude-longitude pairs in the E7 representation
// (degrees multiplied by 10**7 and rounded to the nearest integer).
// Latitudes should be in the range +/- 90 degrees and longitude should be in
// the range +/- 180 degrees (inclusive).
message Point {int32 latitude = 1;int32 longitude = 2;
}// A latitude-longitude rectangle, represented as two diagonally opposite
// points "lo" and "hi".
message Rectangle {// One corner of the rectangle.Point lo = 1;// The other corner of the rectangle.Point hi = 2;
}// A feature names something at a given point.
//
// If a feature could not be named, the name is empty.
message Feature {// The name of the feature.string name = 1;// The point where the feature is detected.Point location = 2;
}// A RouteNote is a message sent while at a given point.
message RouteNote {// The location from which the message is sent.Point location = 1;// The message to be sent.string message = 2;
}// A RouteSummary is received in response to a RecordRoute rpc.
//
// It contains the number of individual points received, the number of
// detected features, and the total distance covered as the cumulative sum of
// the distance between each point.
message RouteSummary {// The number of points received.int32 point_count = 1;// The number of known features passed while traversing the route.int32 feature_count = 2;// The distance covered in metres.int32 distance = 3;// The duration of the traversal in seconds.int32 elapsed_time = 4;
}
生成的两个文件包括message实现和用于server,client的代码
在pb.go文件中对于每个message实现了其type,比如对于Rectangle
type Rectangle struct {state protoimpl.MessageStatesizeCache protoimpl.SizeCacheunknownFields protoimpl.UnknownFields// One corner of the rectangle.Lo *Point `protobuf:"bytes,1,opt,name=lo,proto3" json:"lo,omitempty"`// The other corner of the rectangle.Hi *Point `protobuf:"bytes,2,opt,name=hi,proto3" json:"hi,omitempty"`
}
func (x *Rectangle) Reset() {*x = Rectangle{}if protoimpl.UnsafeEnabled {mi := &file_routeguide_route_guide_proto_msgTypes[1]ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))ms.StoreMessageInfo(mi)}
}func (x *Rectangle) String() string {return protoimpl.X.MessageStringOf(x)
}func (*Rectangle) ProtoMessage() {}func (x *Rectangle) ProtoReflect() protoreflect.Message {mi := &file_routeguide_route_guide_proto_msgTypes[1]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 Rectangle.ProtoReflect.Descriptor instead.
func (*Rectangle) Descriptor() ([]byte, []int) {return file_routeguide_route_guide_proto_rawDescGZIP(), []int{1}
}func (x *Rectangle) GetLo() *Point {if x != nil {return x.Lo}return nil
}func (x *Rectangle) GetHi() *Point {if x != nil {return x.Hi}return nil
}
对于Client来说,定义接口.首先使用grpc库中的grpc.ClientConnInterface
作为routeGuideClient的成员.
type routeGuideClient struct {cc grpc.ClientConnInterface
}
给结构体routeGuideClient
实现多个方法,并定义接口
type RouteGuideClient interface {// A simple RPC.//// Obtains the feature at a given position.//// A feature with an empty name is returned if there's no feature at the given// position.GetFeature(ctx context.Context, in *Point, opts ...grpc.CallOption) (*Feature, error)// A server-to-client streaming RPC.//// Obtains the Features available within the given Rectangle. Results are// streamed rather than returned at once (e.g. in a response message with a// repeated field), as the rectangle may cover a large area and contain a// huge number of features.ListFeatures(ctx context.Context, in *Rectangle, opts ...grpc.CallOption) (RouteGuide_ListFeaturesClient, error)// A client-to-server streaming RPC.//// Accepts a stream of Points on a route being traversed, returning a// RouteSummary when traversal is completed.RecordRoute(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RecordRouteClient, error)// A Bidirectional streaming RPC.//// Accepts a stream of RouteNotes sent while a route is being traversed,// while receiving other RouteNotes (e.g. from other users).RouteChat(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RouteChatClient, error)
}
然后通过NewRouteGuideClient
返回结构体
func NewRouteGuideClient(cc grpc.ClientConnInterface) RouteGuideClient {return &routeGuideClient{cc}
}
实现结构体的方法
func (c *routeGuideClient) GetFeature(ctx context.Context, in *Point, opts ...grpc.CallOption) (*Feature, error) {out := new(Feature)err := c.cc.Invoke(ctx, RouteGuide_GetFeature_FullMethodName, in, out, opts...)if err != nil {return nil, err}return out, nil
}func (c *routeGuideClient) ListFeatures(ctx context.Context, in *Rectangle, opts ...grpc.CallOption) (RouteGuide_ListFeaturesClient, error) {stream, err := c.cc.NewStream(ctx, &RouteGuide_ServiceDesc.Streams[0], RouteGuide_ListFeatures_FullMethodName, opts...)if err != nil {return nil, err}x := &routeGuideListFeaturesClient{stream}if err := x.ClientStream.SendMsg(in); err != nil {return nil, err}if err := x.ClientStream.CloseSend(); err != nil {return nil, err}return x, nil
}
如果涉及stream还有新的结构,定义结构体,方法和接口
type RouteGuide_ListFeaturesClient interface {Recv() (*Feature, error)grpc.ClientStream
}type routeGuideListFeaturesClient struct {grpc.ClientStream
}func (x *routeGuideListFeaturesClient) Recv() (*Feature, error) {m := new(Feature)if err := x.ClientStream.RecvMsg(m); err != nil {return nil, err}return m, nil
}
对于server类似,定义接口
type RouteGuideServer interface {// A simple RPC.//// Obtains the feature at a given position.//// A feature with an empty name is returned if there's no feature at the given// position.GetFeature(context.Context, *Point) (*Feature, error)// A server-to-client streaming RPC.//// Obtains the Features available within the given Rectangle. Results are// streamed rather than returned at once (e.g. in a response message with a// repeated field), as the rectangle may cover a large area and contain a// huge number of features.ListFeatures(*Rectangle, RouteGuide_ListFeaturesServer) error// A client-to-server streaming RPC.//// Accepts a stream of Points on a route being traversed, returning a// RouteSummary when traversal is completed.RecordRoute(RouteGuide_RecordRouteServer) error// A Bidirectional streaming RPC.//// Accepts a stream of RouteNotes sent while a route is being traversed,// while receiving other RouteNotes (e.g. from other users).RouteChat(RouteGuide_RouteChatServer) errormustEmbedUnimplementedRouteGuideServer()
}
实现server和client
当使用protoc生成文件之后,就可以写server和client了.
server
定义结构体,注意定义时加上pb.UnimplementedRouteGuideServer
这样避免有些方法没有实现.
type routeGuideServer struct {pb.UnimplementedRouteGuideServersavedFeatures []*pb.Feature // read-only after initializedmu sync.Mutex // protects routeNotesrouteNotes map[string][]*pb.RouteNote
}
实现接口满足的方法.
func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error)
func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer)
func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer)
func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer)
然后使用tcp链接新建grpc服务
func main() {flag.Parse()lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))if err != nil {log.Fatalf("failed to listen: %v", err)}var opts []grpc.ServerOptionif *tls {if *certFile == "" {*certFile = data.Path("x509/server_cert.pem")}if *keyFile == "" {*keyFile = data.Path("x509/server_key.pem")}creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)if err != nil {log.Fatalf("Failed to generate credentials: %v", err)}opts = []grpc.ServerOption{grpc.Creds(creds)}}grpcServer := grpc.NewServer(opts...)pb.RegisterRouteGuideServer(grpcServer, newServer())grpcServer.Serve(lis)
}
上面使用pb.RegisterRouteGuideServer
注册服务,参数分别是grpc服务和newServer
返回的结构体
client
func printFeature(client pb.RouteGuideClient, point *pb.Point) {log.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()feature, err := client.GetFeature(ctx, point)if err != nil {log.Fatalf("client.GetFeature failed: %v", err)}log.Println(feature)
}
利用context创建ctx和cancel,利用client := pb.NewRouteGuideClient(conn)
创建client调用方法.
NewRouteGuideClient
返回对应的client接口
func NewRouteGuideClient(cc grpc.ClientConnInterface) RouteGuideClient {return &routeGuideClient{cc}
}
gRPC面临的挑战
虽然gRPC确实允许您使用这些较新的技术,但gRPC服务的原型设计更具挑战性,因为无法使用Postman HTTP客户端等工具来轻松地与您公开的gRPC服务交互。你确实有一些选择可以实现这一点,但这并不是一种在本地就可以获得的东西。
有一些选项可以使用诸如特使之类的工具来反转代理标准JSON请求,并将其转码为正确的数据格式,但这是一个额外的依赖项,对于简单的项目来说,设置它可能很困难。
参考资料
- Documentation | gRPC
- Go gRPC Beginners Tutorial | TutorialEdge.net
- [Go RPC开发简介 - 官方RPC库 - 《Go RPC开发指南 中文文档]》 - 书栈网 · BookStack
- RESTful API 最佳实践 - 阮一峰的网络日志 (ruanyifeng.com)
- Basics tutorial | Go | gRPC
- What is gRPC? | gRPC
如有疑问,欢迎各位交流!
服务器配置
宝塔:宝塔服务器面板,一键全能部署及管理
云服务器:阿里云服务器
Vultr服务器
GPU服务器:Vast.ai
相关文章:

【gRPC学习】使用go学习gRPC
个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 RPC是远程调用,而google实现了grpc比较方便地实现了远程调用,gRPC是一个现代的开源远程过程调用(RPC)框架 概念介绍 在gRPC中,客户端应用程序可以直接调用另一台计算机上的服务器应用程序上的方法&#…...

C语言中常用的字符串函数(strlen、sizeof、sscanf、sprintf、strcpy)
C语言中常用的字符串函数 文章目录 C语言中常用的字符串函数1 strlen函数2 sizeof函数2.1 sizeof介绍2.2 sizeof用法 3 sscanf函数3.1 sscanf介绍3.2 sscanf用法3.3 sscanf高级用法 4 sprintf函数4.1 背景4.2 sprintf用法 5 strcpy函数5.1 strcpy介绍5.1 strcpy用法 1 strlen函…...
域名解析服务器:连接你与互联网的桥梁
域名解析服务器:连接你与互联网的桥梁 大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天,我们将探讨一个网络世界中至关重要却鲜为人知的角…...
理论物理在天线设计和射频电路设计中的应用
理论物理的基本原理可以应用于电路中的电磁场分析和电磁波传播问题,例如天线设计和射频电路设计。通过应用麦克斯韦方程组和电磁波传播理论,可以优化电路的性能,提高天线的辐射效率和射频电路的传输效率。麦克斯韦方程组是描述电磁场行为的基…...

MySql01:初识
1.mysql数据库2.配置环境变量3. 列的类型和属性,索引,注释3.1 类型3.2 属性3.3 主键(主键索引)3.4 注释 4.结构化查询语句分类:5.列类型--表列类型设置 1.mysql数据库 数据库: 数据仓库,存储数据,以前我…...

Python——运算符
num 1 num 1 print("num1:", num) num - 1 print("num-1:", num) num * 4 print("num*4:", num) num / 4 print("num/4:", num) num 3 num % 2 print("num%2:", num) num ** 2 print("num**2:", num) 运行结果…...

赋能软件开发:生成式AI在优化编程工作流中的应用与前景
随着人工智能(AI)技术的快速发展,特别是生成式AI模型如GPT-3/4的出现,软件开发行业正经历一场变革,这些模型通过提供代码生成、自动化测试和错误检测等功能,极大地提高了开发效率和软件质量。 本文旨在深入…...

通过盲对抗性扰动实时击败基于DNN的流量分析系统
文章信息 论文题目:Defeating DNN-Based Traffic Analysis Systems in Real-Time With Blind Adversarial Perturbations 期刊(会议):30th USENIX Security Symposium 时间:2021 级别:CCF A 文章链接&…...

【Project】TPC-Online Module (manuscript_2024-01-07)
PRD正文 一、概述 本模块实现隧道点云数据的线上汇总和可视化。用户可以通过注册和登录功能进行身份验证,然后上传原始隧道点云数据和经过处理的数据到后台服务器。该模块提供数据查询、筛选和可视化等操作,同时支持对指定里程的分段显示和点云颜色更改…...

通过cpolar在公网访问本地网站
通过cpolar可以轻松将本地网址映射到公网进行访问,下面简要介绍一下实现步骤。 目录 一、cpolar下载 二、安装 三、使用 3.1 登录 3.2 创建隧道 一、cpolar下载 cpolar官网地址:cpolar - secure introspectable tunnels to localhost 通过QQ邮箱…...
Prokka: ubuntu安装的时候出现错误
[14:10:57] Running: cat /app/prokka_result/ref_file/ref_file.HAMAP.hmm.tmp.77.faa | parallel --gnu --plain -j 2 --block 108208 --recstart ‘>’ --pipe hmmscan --noali --notextw --acc -E 1e-09 --cpu 1 /opt/prokka/db/hmm/HAMAP.hmm /dev/stdin > /app/pro…...
安全防御之密码技术
密码学是信息安全的基础技术之一,是达到信息系统安全等级保护要求的核心技术支持,在身份验证、访问控制、文件加密、数据加密和安全传输中都得到广泛应用。其核心目标是保证信息的机密性、完整性和可用性。 密码学包括加密和解密两个部分。一般过程是&am…...

一文读懂「多模态大模型」
学习资源 5-多模态大模型一统NLP和CV 1.多模态大模型的基本原理 2.常见的多模态大模型 https://www.bilibili.com/video/BV1NN41177Zp?p5&vd_sourcef27f081fc77389ca006fcebf41bede2d 3.多模态大模型如_哔哩哔哩_bilibili 强强联手!科大讯飞和中科院终于把【…...
深入PostgreSQL:高级函数用法探索
写在开头 在 PostgreSQL 中,函数是数据库开发和管理中强大而灵活的工具。通过深入了解高级函数用法,我们可以更有效地利用 PostgreSQL 的功能。在本文中,我们将探讨一些看起来比较高级的 PostgreSQL 函数用法,包括窗口函数、自定义聚合函数、JSONB 类型函数、全文搜索、PL…...
huggingface实战bert-base-chinese模型(训练+预测)
文章目录 前言一、bert模型词汇映射说明二、bert模型输入解读1、input_ids说明2、attention_mask说明3、token_type_ids说明4、模型输入与vocab映射内容二、huggingface模型数据加载1、数据格式查看2、数据dataset处理3、tokenizer处理dataset数据三、huggingface训练bert分类模…...

CCS安装和导入项目及编译教程
1. CCS安装# 在 TI官网 下载离线版(offline)。 Code Composer Studio Downloads 页面上有license 信息:这么看来是免费的,爱了爱了 Licensing: CCSv7 and later are Technology Software Publicly Available (TSPA) compliant.…...
在React里面使用mobx状态管理详细步骤
1、安装MobX和MobX React: 在你的项目目录下运行以下命令安装MobX和MobX React: npm install mobx mobx-react2、创建MobX Store: 创建一个用于管理状态的MobX Store。这个Store应该包含你希望全局管理的状态和相关的操作。以下是一个简单…...

1.6PTA集练7-5~7-24、7-1、7-2,堆的操作,部落冲突(二分查找)
7-5 大師と仙人との奇遇 分数 20 #include<iostream> #include<queue> using namespace std; int n; long long ans0,num; priority_queue<long long,vector<long long>,greater<long long>>q;//记录之前买的,用小顶堆,最上面就是最…...
uniapp向上拉加载,下拉刷新
目录 大佬1大佬2 大佬1 大佬地址:https://blog.csdn.net/wendy_qx/article/details/135077822 大佬2 大佬2:https://blog.csdn.net/chen__hui/article/details/122497140...

目标检测脚本之mmpose json转yolo txt格式
目标检测脚本之mmpose json转yolo txt格式 一、需求分析 在使用yolopose及yolov8-pose 网络进行人体姿态检测任务时,有时需要标注一些特定场景的中的人型目标数据,用来扩充训练集,提升自己训练模型的效果。因为单纯的人工标注耗时费力&…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...