手撕RPC协议源码:C++开发者必须掌握的7个通信底层知识点

C++极简版的RPC框架   前言      RPC采用客户机/服务器模式实现两个进程之间的相互通信,socket是RPC经常采用的通信手段之一。当然,除了socket,RPC还有其他的通信方法:http、管道。。。网络开源的RPC框架也比较多,一个功能比较完善的RPC框架代码比较多,如何快速的从这些代码盲海中梳理清楚主要脉络,对于初学者来说比较困难,本文介绍之前自己实现的一个C++极简版的RPC框架,代码只有100多行,... 阅读详情

第一章:RPC协议的核心架构与C++实现概述

远程过程调用(Remote Procedure Call, RPC)是一种允许程序调用位于不同地址空间中的子程序的通信协议,通常用于分布式系统中服务间的交互。在现代高性能后端架构中,基于C++实现的RPC框架因其低延迟和高吞吐量特性被广泛采用。一个典型的RPC核心架构包含客户端存根(Stub)、服务器端骨架(Skeleton)、序列化模块、网络传输层以及服务注册与发现机制。

核心组件构成

  • 客户端存根:负责封装本地调用,将参数序列化并发送至服务端
  • 服务器骨架:接收请求,反序列化数据并调用实际服务方法
  • 序列化协议:如Protobuf、FlatBuffers,用于高效数据编码
  • 传输层:基于TCP或HTTP/2实现可靠通信
  • 服务治理:支持负载均衡、超时控制与容错机制

C++中的基础实现逻辑


// 示例:简单的RPC客户端调用伪代码
class RpcClient {
public:
    template<typename Request, typename Response>
    bool Call(const std::string& method, const Request& req, Response* resp) {
        // 1. 序列化请求对象
        std::string data = Serialize(req);
        // 2. 通过socket发送到服务端
        socket_.Send(method + "\n" + data);
        // 3. 等待响应并反序列化
        std::string response_data = socket_.Receive();
        return Deserialize(response_data, resp);
    }
};
组件常用技术选型说明
序列化Protobuf, Thrift跨语言、高效的数据编码方式
传输协议TCP, HTTP/2gRPC 使用 HTTP/2 实现多路复用
异步处理Boost.Asio, libevent提升并发能力的关键支撑
graph LR A[Client Application] --> B[Client Stub] B --> C[Network Layer] C --> D[Server Skeleton] D --> E[Server Application] E --> D D --> C C --> B B --> A

第二章:网络通信底层机制剖析

2.1 套接字编程基础与C++封装实践

在现代网络通信中,套接字(Socket)是实现进程间数据交换的核心机制。基于TCP/IP协议栈的套接字编程,通常涉及创建、绑定、监听、连接和数据收发等系统调用。
核心流程概述
典型的TCP服务端流程包括:
  1. 调用 socket() 创建套接字
  2. 使用 bind() 绑定地址和端口
  3. 通过 listen() 启动监听
  4. 接受连接并使用 recv() 和 send() 进行通信
C++面向对象封装
为提升代码可维护性,可将套接字操作封装为类:
class TcpSocket {
private:
    int sockfd;
public:
    TcpSocket() { sockfd = socket(AF_INET, SOCK_STREAM, 0); }
    bool bind(const char* ip, int port);
    bool listen(int backlog = 10);
    int accept(); // 返回客户端连接描述符
    ~TcpSocket() { if(sockfd) close(sockfd); }
};
上述代码定义了基本的TCP套接字类,构造函数中初始化文件描述符,析构时自动释放资源。关键方法如 bind() 需组合使用 sockaddr_in 结构体设置IP和端口,并调用系统API完成绑定操作。这种封装方式屏蔽底层细节,便于上层应用复用。

2.2 TCP粘包问题分析与消息边界处理

TCP是面向字节流的协议,不保证消息边界,导致接收方可能将多个发送消息合并或拆分接收,即“粘包”问题。其根本原因在于TCP仅负责按序传输字节流,而应用层未定义明确的消息分隔机制。
常见解决方案
  • 定长消息:每个消息固定长度,不足补空,简单但浪费带宽;
  • 特殊分隔符:如换行符、\0等标识消息结束,适用于文本协议;
  • 消息长度前缀:在消息头部携带数据长度,最常用且高效。
基于长度前缀的实现示例(Go)
type Message struct {
    Length uint32
    Data   []byte
}

func (m *Message) Marshal() []byte {
    var buf bytes.Buffer
    binary.Write(&buf, binary.BigEndian, m.Length)
    buf.Write(m.Data)
    return buf.Bytes()
}
上述代码使用大端序写入消息长度(4字节),后接实际数据。接收方先读取4字节获取长度,再读取对应字节数,从而准确切分消息边界。

2.3 非阻塞IO与epoll在高性能RPC中的应用

在构建高并发RPC服务时,传统阻塞IO模型难以应对海量连接。非阻塞IO结合事件驱动机制成为突破性能瓶颈的关键。
epoll的核心优势
epoll通过就绪事件通知机制,避免遍历所有文件描述符,显著提升I/O多路复用效率。相比select/poll,其时间复杂度为O(1),适用于万级并发场景。
典型代码实现

int epoll_fd = epoll_create1(0);
struct epoll_event event, events[MAX_EVENTS];
event.events = EPOLLIN | EPOLLET;
event.data.fd = sockfd;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sockfd, &event);

while (running) {
    int n = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
    for (int i = 0; i < n; i++) {
        if (events[i].data.fd == sockfd) {
            accept_connection(sockfd);
        } else {
            read_data(events[i].data.fd);
        }
    }
}
上述代码使用边缘触发(EPOLLET)模式,仅在状态变化时通知,减少系统调用次数。epoll_wait阻塞等待事件到来,实现单线程处理数千连接。
在RPC框架中的作用
  • 提升连接管理效率,降低线程上下文切换开销
  • 支持异步请求处理,增强系统吞吐能力
  • 与Reactor模式结合,构建可扩展的网络层

2.4 连接管理与心跳机制的设计与实现

在高并发通信系统中,连接的稳定性直接影响服务可用性。连接管理模块负责客户端连接的建立、维持与释放,结合事件驱动模型实现海量连接的高效管理。
心跳检测机制
通过周期性发送心跳包探测连接活性,避免半打开连接占用资源。服务端设置空闲超时阈值,超过指定时间未收到数据则关闭连接。
// 心跳处理逻辑示例
ticker := time.NewTicker(30 * time.Second)
go func() {
    for range ticker.C {
        if lastPing.Before(time.Now().Add(-60 * time.Second)) {
            conn.Close()
        }
    }
}()
上述代码每30秒检查最后一次通信时间,若超过60秒未更新,则判定连接失效并关闭。
连接状态机
使用状态机管理连接生命周期,包含“已连接”、“活跃”、“空闲”、“断开”等状态,确保状态迁移的原子性和一致性。

2.5 异步通信模型与回调机制的C++表达

在现代C++系统设计中,异步通信模型通过非阻塞调用提升并发性能,而回调机制则是其实现的核心手段之一。借助函数对象与lambda表达式,C++能够以类型安全的方式封装异步逻辑。
基于std::function的回调注册

#include <functional>
#include <thread>
#include <iostream>

void async_op(std::function<void(int)> callback) {
    std::thread([callback]() {
        int result = 42; // 模拟异步计算
        callback(result);
    }).detach();
}
上述代码中,std::function<void(int)> 作为回调签名,允许传入函数指针、lambda或仿函数。异步操作在独立线程中执行,完成后触发回调,实现控制反转。
事件处理流程

请求发起 → 后台线程处理 → 结果就绪 → 回调分发 → 主线程响应

第三章:序列化与反序列化的性能优化

3.1 Protobuf与FlatBuffers在RPC中的选型对比

在高性能RPC系统中,Protobuf与FlatBuffers作为主流序列化方案各有优劣。Protobuf由Google设计,具备良好的跨语言支持与成熟的生态体系。
序列化性能对比
  • Protobuf需序列化/反序列化全过程,带来CPU开销
  • FlatBuffers支持“零拷贝”访问,直接读取二进制数据
典型使用场景代码示例

// FlatBuffers 示例:直接访问偏移量
auto message = GetMessage(buffer);
std::cout << message->text()->str();
上述代码无需解析即可访问字段,适用于高频调用场景。而Protobuf需先解析:

Person person;
person.ParseFromArray(data, size);
std::cout << person.name();
此过程涉及内存分配与字段填充,延迟更高。
选型建议
维度ProtobufFlatBuffers
编译支持需生成代码需schema预编译
内存占用中等低(无副本)

3.2 自定义二进制协议的设计原则与编码实战

设计原则:精简、可扩展与对齐
自定义二进制协议需遵循紧凑编码、字段对齐和版本兼容性。采用固定头部+变长负载结构,头部包含魔数、版本、命令码、数据长度和校验和。
字段长度(字节)说明
Magic2标识协议起始,如 0xABCD
Version1协议版本号
Command1操作指令类型
Length4负载数据长度
Checksum4校验值(如CRC32)
编码实现示例

type Header struct {
    Magic   uint16
    Version uint8
    Command uint8
    Length  uint32
    Checksum uint32
}
// 序列化为字节流,注意字节序:使用binary.BigEndian
buf := new(bytes.Buffer)
binary.Write(buf, binary.BigEndian, header)
该代码将协议头按大端序写入缓冲区,确保跨平台一致性。Magic用于防止粘包,Checksum保障传输完整性。

3.3 零拷贝技术在序列化过程中的应用探索

在高性能数据传输场景中,序列化与反序列化的效率直接影响系统吞吐。传统方式中,对象需先序列化至中间缓冲区,再复制到网络输出流,产生多次内存拷贝。零拷贝技术通过直接内存访问减少冗余复制,显著提升性能。
内存映射与直接缓冲区
Java NIO 提供 ByteBuffer.allocateDirect() 创建堆外内存,避免 JVM 堆与内核空间间的重复拷贝。结合 FileChannel.map() 实现内存映射文件,可将序列化数据直接写入映射区域。

ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
byte[] data = serializer.serialize(obj);
buffer.put(data);
buffer.flip();
socketChannel.write(buffer);
上述代码中,序列化后的字节数组写入直接缓冲区,通过 SocketChannel 直接发送,避免中间拷贝环节。参数 allocateDirect 分配堆外内存,降低 GC 压力。
序列化框架的零拷贝优化
现代序列化库如 Protobuf 和 FlatBuffers 支持构建时指定直接缓冲区,实现序列化与传输的无缝衔接。FlatBuffers 更允许直接访问序列化数据而无需反序列化,进一步减少内存操作。
技术是否支持零拷贝典型应用场景
Protobuf部分支持RPC 数据传输
FlatBuffers完全支持高频读取场景

第四章:服务调用与远程方法执行机制

4.1 客户端存根与服务端骨架的生成原理

在远程过程调用(RPC)框架中,客户端存根(Stub)和服务端骨架(Skeleton)是实现透明远程调用的核心组件。它们通过代理模式屏蔽底层通信细节,使开发者如同调用本地方法一般发起远程请求。
客户端存根的作用机制
客户端存根作为服务接口的本地代理,负责将方法调用封装为网络请求。它序列化参数、构造调用消息,并交由通信层发送至服务端。

public class UserServiceStub implements UserService {
    private RpcClient client;

    public User findById(int id) {
        // 封装请求并发送
        Request req = new Request("UserService.findById", new Object[]{id});
        Response resp = client.send(req);
        return (User) resp.getResult();
    }
}
上述代码展示了存根如何将方法调用转化为远程请求。参数被封装进 `Request` 对象,经序列化后通过网络传输。
服务端骨架的分发逻辑
服务端骨架接收反序列化的请求,定位具体服务实例并执行方法调用,最终将结果回传。
  • 监听网络请求并解析消息体
  • 根据接口名和方法名查找实现类
  • 反射调用目标方法并捕获返回值
  • 封装响应数据并返回给客户端

4.2 请求-响应模型的线程安全实现

在高并发场景下,请求-响应模型必须保障共享资源的线程安全性。使用互斥锁(Mutex)是常见手段,可防止多个线程同时访问临界区。
数据同步机制
通过读写锁优化性能,允许多个读操作并发执行,仅在写入时独占资源:

var mu sync.RWMutex
var responseCache = make(map[string]string)

func GetResponse(key string) string {
    mu.RLock()
    defer mu.RUnlock()
    return responseCache[key]
}

func SetResponse(key, value string) {
    mu.Lock()
    defer mu.Unlock()
    responseCache[key] = value
}
上述代码中,sync.RWMutex 提升了读密集场景的吞吐量。Rlock() 允许多协程读取,Lock() 确保写操作原子性。
并发控制策略对比
策略适用场景优点缺点
互斥锁写频繁简单可靠读并发受限
读写锁读多写少提升读性能写饥饿风险

4.3 超时控制与重试机制的工程化设计

在分布式系统中,网络波动和瞬时故障不可避免,合理的超时控制与重试机制是保障服务稳定性的关键。
超时策略的设计
应根据接口响应分布设定动态超时时间,避免全局硬编码。常见做法是结合 P99 响应时间进行基线设定,并预留突发延迟缓冲。
智能重试机制
采用指数退避 + 随机抖动策略可有效缓解服务雪崩。例如:
func WithRetry(backoff time.Duration, maxRetries int) error {
    for i := 0; i < maxRetries; i++ {
        err := callRemote()
        if err == nil {
            return nil
        }
        jitter := time.Duration(rand.Int63n(int64(backoff)))
        time.Sleep(backoff + jitter)
        backoff *= 2 // 指数增长
    }
    return errors.New("max retries exceeded")
}
上述代码实现了带抖动的指数退避重试,backoff 初始为 100ms,每次翻倍,jitter 防止多个实例同时重试造成压力集中。

4.4 分布式上下文传递与链路追踪集成

在微服务架构中,跨服务调用的上下文传递与链路追踪是可观测性的核心。为实现请求链路的完整追踪,需将 traceId、spanId 等上下文信息通过请求头在服务间透传。
上下文传播机制
通常使用拦截器在 HTTP 请求中注入追踪上下文。例如,在 Go 的 OpenTelemetry 实现中:
propagator := propagation.TraceContext{}
carrier := propagation.HeaderCarrier(req.Header)
propagator.Inject(context.Background(), carrier)
上述代码将当前上下文中的 traceparent 信息注入到 HTTP 头中,确保下游服务可提取并延续链路。
链路数据关联
各服务上报的 Span 需包含统一 traceId,并通过 parentSpanId 建立层级关系。常见字段如下:
字段名说明
traceId全局唯一,标识一次完整调用链
spanId当前操作的唯一标识
parentSpanId父级 Span 的 ID,构建调用树

第五章:从源码到生产:构建高可用RPC框架的关键路径

服务发现与注册的动态集成
在微服务架构中,RPC框架必须支持动态服务注册与发现。使用Consul或etcd作为注册中心时,客户端需定期发送心跳并监听节点变化。以下为Go语言实现的服务注册代码片段:

// 向etcd注册服务实例
cli, _ := clientv3.New(clientv3.Config{Endpoints: []string{"localhost:2379"}})
leaseResp, _ := cli.Grant(context.TODO(), 10) // 10秒TTL
cli.Put(context.TODO(), "/services/user/1", "192.168.1.100:8080", clientv3.WithLease(leaseResp.ID))
// 续约以维持存活
keepAlive, _ := cli.KeepAlive(context.TODO(), leaseResp.ID)
负载均衡策略的选择与实现
高可用RPC框架依赖智能负载均衡来分配请求。常见的策略包括轮询、加权轮询和一致性哈希。下表对比了不同场景下的适用性:
策略适用场景优点缺点
轮询节点性能一致简单公平忽略负载差异
一致性哈希缓存亲和性要求高减少数据迁移实现复杂
熔断与降级机制的实战配置
为防止雪崩效应,集成Hystrix或Resilience4j风格的熔断器至关重要。建议设置如下参数:
  • 请求失败率阈值设为50%
  • 最小请求数量为20次(避免过早触发)
  • 熔断持续时间为30秒
客户端 → 负载均衡 → 熔断器 → 实际RPC调用 → 序列化/反序列化 → 服务端处理

第六章:分布式环境下的一致性与容错策略

第七章:现代C++特性在RPC框架中的深度应用

别再手动更新Excel了!用Jira看板管理你的个人项目(附保姆级配置流程) 本文详细介绍了如何利用Jira看板替代Excel进行个人项目管理,提供从注册到配置的保姆级教程。通过极简看板模式、自动化规则和数据分析功能,帮助用户实现任务可视化、协作高效化和提醒自动化,大幅提升个人工作效率。特别适合需要管理复杂个人项目的用户。 阅读详情

相关推荐

Paypal开发者中心获取“ClientId”和“ClientSecret”参数

正式环境设置 1、登录到 paypal开发者中心 网址:https://developer.paypal.com/developer/ 点击右上角登录按钮登录 2、左侧栏 - 我的应用程序和凭证 - 点击“创建新应用” 新注册的paypal账号,需要进行邮箱验证,验证通过后,需要等待一段时间(或重新登录),才会出现相关设置项位置 验证邮箱通过后,点击创建新应用 3、按提示填写,保存创建应用 4、点击刚创建的应用进入应用详情页 5、应用详情页获得网站开发人员所需要的“ClientId”和“Client

龚清林的博客 1万+

用libhv和protobuf手搓一个C++ RPC框架:从proto定义到服务端完整流程

本文详细介绍了如何使用libhv和protobuf从零构建一个C++ RPC框架,涵盖从proto定义到服务端实现的完整流程。通过libhv网络库和protobuf序列化工具,开发者可以快速搭建高性能的RPC框架,适用于分布式系统开发。文章重点讲解了网络层实现、消息协议设计、服务路由等核心组件,并提供了优化技巧和监控指标收集方法。

weixin_30530939的博客 581

十大排序算法详解(一)冒泡排序、选择排序、插入排序、快速排序、希尔排序

冒泡排序、选择排序、插入排序、快速排序、希尔排序

HK的博客 18万+

# KVstorageBaseRaft-cpp 项目 RPC 模块源码学习

KVstorageBaseRaft-cpp 是一个基于 Raft 算法的分布式 KV 存储系统

永不止息 772

高性能网站设计之缓存更新的套路

看到好些人在写更新缓存数据代码时,先删除缓存,然后再更新数据库,而后续的操作会把数据再装载的缓存中。然而,这个是逻辑是错误的。试想,两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的数据是脏的,而且还一直这样脏下去了。 我不知道为什么这么多人用的都是这

代码技巧 1万+

Python XML 转 JSON,XML 转字典

今天我们将学习如何在 Python 中将 XML 转换为 JSON 和 XML 转换为字典。我们可以使用 Python 的xmltodict模块来读取 XML 文件并将其转换为字典或 JSON 数据。我们还可以在大型 XML 文件上进行流式处理,并将其转换为字典。在进入编码部分之前,让我们首先了解为什么需要进行 XML 转换。

rubys_的专栏 2502

c++socket多个客户端通过不同端口与一个服务端通信_手写RPC,深入底层理解整个RPC通信...

一、前言RPC,远程过程调用,调用远程方法像调用本地方法一样。RPC交互分为客户端和服务端,客户端调用服务端方法,服务端接收数据并打印到控制台,并response响应给客户端。RPC和HTTP的联系与区别联系:都是远程通信的网络协议,任何网络协议都包括语法、语义、时序三个特征。区别:HTTP协议是应用层协议,更多地用于前后端通信或移动端、PC端与后端通信,其他的常用应用层协议还包括SSH协议、ft...

weixin_42347739的博客 740

【雕爷学编程】Arduino智能家居之DS18B20温度传感器

1、温度和湿度控制:通过连接温度传感器和湿度传感器,Arduino可以实时监测室内环境的温度和湿度,并通过控制空调、加热器或加湿器等执行器,实现室内温湿度的自动调节。设计用户友好的界面和操作方式,提供简单直观的控制和反馈机制,以及考虑用户习惯和需求,能够提升系统的整体用户体验。这意味着用户可以根据自己的需求和创意,自定义和定制智能家居系统的功能和外观。5、能源管理:Arduino可以与电能监测模块和智能插座等设备结合使用,实时监测家庭能源的使用情况,并通过自动控制电器设备的开关,实现能源的有效管理和节约。

雕爷学编程 2874

【亲测免费】 libjson-rpc-cpp 教程

**libjson-rpc-cpp** 是一个C++编写的JSON-RPC(JSON远程过程调用)框架,支持JSON-RPC 2.0及部分1.0规范。它提供了一个完整的客户端和服务器实现,并包含一个名为`jsonrpcstub`的工具,可以自动生成客户端和服务端的存根类。该项目具有跨平台的支持,可在Linux和OS X上构建,并以MIT许可证开放源码。 特点: - JSON-RPC 2.0完整支...

gitblog_00938的博客 1049

【ComfyUI】SDXL + 单LoRA 房屋平面图渲染装修

本文介绍了一种基于ComfyUI的室内平面设计图自动生成效果图的工作流。该流程通过导入房屋平面图,结合SDXL室内设计模型与北欧风格LoRA模块,快速生成多房间效果展示。工作流包含图像输入、文本处理、模型加载和图像生成等环节,支持风格化渲染和细节补充,适用于建筑设计、家装展示、房地产营销等场景。核心采用SDXL通用室内设计模型和北欧极简LoRA,通过节点衔接实现自动化批量生成,能在短时间内将平面方案转化为逼真的三维效果图。该技术可提升设计呈现效率,辅助客户决策,并应用于教学研究领域。

Mr数据杨 3659

MIPI D-PHY IP 使用说明(一)

目录 前言 一、IP 特点 二、IP 可用性 三、IP 总览 四、IP 声明 五、IP 结构 六、IP 分流桥 模式 七、端口描述 1、PPI 接口信号 1、常规 PPI控制信号 2、发送模式 时钟通道 高速 PPI 信号 3、发送模式 时钟通道 逃逸模式PPI 信号 4、发送模式 数据通道 高速 PPI 信号 5、发送模式 数据通道 控制接口PPI 信号 6、发送模式 ...

记录所学,分享知识,结识挚友 2504

开源项目libjson-rpc-cpp快速指南及问题解决

libjson-rpc-cpp是一个跨平台的C++框架,专为JSON-RPC(JSON远程过程调用)设计。该框架支持JSON-RPC 2.0完全兼容以及部分1.0规范,提供了一个强大的工具集,包括客户端与服务器端的支持,一个自动生成服务端与客户端桩类的工具`jsonrpcstub`,并具有HTTP+TCP的服务端与客户端实现。此项目采用MIT许可证,非常适合于希望快速集成RPC功能的C++项目。它...

gitblog_00824的博客 1222

MIPI CPHY学习笔记02:TX物理层一致性测试项解析(HS信令模式)第一部分

在手机、平板等移动设备中,MIPI C-PHY是连接相机、显示屏等高速外设的“数据高速公路”。高速(HS)信令模式就是这条公路的“快车道”,专门用于传输高清图像、视频等大容量数据,既要保证传输速率,又要维持信号稳定。物理层一致性测试是对这条“快车道”的全面质检,确保高速传输下数据不卡顿、不失真。今天我们聚焦MIPI C-PHY TX(发射端)的Group 2 HS信令测试,用通俗语言拆解22个核心测试项(含2个过时项),看懂高速信号的合格标准。

一只豌豆象的博客 289

【C++】基于C++的RPC分布式网络通信框架(二)

在网上关于RPC分布式网络通信框架的文章数不胜数,原本不打算写这篇文章,但是网上的文章总给人一种残缺美,我是一个追求完美的人,所以还是打算站在巨人的肩膀上去完善大神的两篇文章。并补充一些关于这个项目的面试细节(挖个坑 等我找到工作后)。RPC框架基础概念篇C++实现轻量级RPC分布式网络通信框架对于刚接触这个项目的小伙伴来说通常是一脸懵逼,这里给出一个通俗易懂的理解假如说你要买零食,在以前的经济模式下,你会直接去附近的超市,直接进行购买,你买的零食会全部来自于这家超市。

千禧皓月的博客 932

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

现代C++ JSON-RPC实战:基于libjson-rpc-cpp构建轻量级远程服务

远程过程调用(RPC)是分布式系统和微服务架构中的核心技术,它允许程序像调用本地函数一样执行远程服务,从而简化了跨进程或网络边界的通信。其核心原理在于对调用过程进行封装、序列化、网络传输与反序列化,以实现位置透明性。JSON-RPC作为一种基于JSON的轻量级RPC协议,凭借其语言无关、协议简洁和易于调试的特点,在快速原型开发、IoT网关及多语言服务集成等场景中展现出独特的技术价值。libjson-rpc-cpp库为C++开发者提供了完整的JSON-RPC 2.0框架实现,通过规范文件(Specificat

weixin_30873847的博客 398

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

dubbo 源码 v2.7 分析:通信过程及序列化协议

系列文章 dubbo 源码 v2.7 分析:结构、container 入口及线程模型 dubbo 源码 v2.7 分析:SPI 机制 dubbo 源码 v2.7 分析:核心机制(一) dubbo 源码 v2.7 分析:核心机制(二) 关注公众号:程序员架构进阶,每天实时获取更新,上百份面试资料和其他福利等你拿~ 一 摘要 前面我们介绍了dubbo的核心机制,今天将开始分析远程调用流程。毕竟,作为一个rpc框架,远程调用是理论的核心内容。通过对dubbo相关实现的探究,深入了解rpc原理及可能的

程序员架构进阶 728

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

RPC框架源码分析学习(二)

基于Google Protobuf和Muduo网络库的C++版RPC框架源码,重点解读了其核心组件和实现原理

永不止息 1288

C++ JSON-RPC框架libjson-rpc-cpp实战:从原理到异构系统集成

远程过程调用(RPC)是构建分布式系统和实现微服务间通信的核心技术,它允许程序像调用本地函数一样调用网络上的服务。JSON-RPC作为一种基于JSON的轻量级协议,因其文本可读、跨语言支持良好而广泛应用于异构系统集成。libjson-rpc-cpp框架封装了协议解析、网络通信和序列化等底层细节,通过桩代码生成器自动化接口绑定,显著提升了C++项目中RPC开发的效率。该框架支持HTTP、TCP Socket等多种可插拔的传输层,便于根据性能与通用性需求进行选型。在涉及C++与Python、JavaScript

weixin_33738982的博客 342

Jubatus源码解析:从IDL定义到RPC通信的实现细节

Jubatus作为一款分布式在线机器学习框架,其核心通信机制基于RPC(远程过程调用)实现。本文将深入解析Jubatus如何通过IDL(接口定义语言)定义服务接口,并构建高效的RPC通信架构,为开发者理解分布式机器学习系统的底层通信提供清晰指引。 ## IDL接口定义:服务契约的基石 在Jubatus中,所有服务接口都通过IDL文件明确定义,这些文件位于[jubatus/server/serv

gitblog_00418的博客 744

C++实现DBus跨进程通信:从底层libdbus到RPC实战

跨进程通信(IPC)是构建模块化、分布式软件系统的核心技术,它允许不同进程间安全高效地交换数据与调用服务。在Linux桌面环境中,DBus(Desktop Bus)作为标准的IPC机制,其核心原理基于总线架构,通过守护进程(dbus-daemon)进行消息路由,实现了服务发现与远程过程调用(RPC)。这一技术为系统服务集成与应用间通信提供了统一接口,具有松耦合、高可扩展性的价值,广泛应用于桌面环境服务调用、系统状态通知等场景。本文聚焦于使用C++和底层libdbus库,通过一个完整的计算器服务示例,详细拆解

weixin_30843121的博客 280

内容创作与内容策展:30 seconds of code 维护者的社区贡献管理策略

30 seconds of code 是一份面向开发者的高质量代码文章库,其内容由仓库维护者与社区共同维护。本文以仓库更新日志 [231020-content-creator-vs-content-curator.md](https://link.gitcode.com/i/d76079d9a1c8d7c693fe0d43e43c5ca0) 为骨架,剖析维护者在"亲自创作内容"与"策展社区贡献"之

gitblog_00481的博客 1064

微服务开源框架TARS的RPC源码解析 之 初识TARS C++客户端

微服务开源框架TARS的RPC源码解析 之 初识TARS C++客户端什么是TARS初识客户端CommunicatorServantProxy与ServantProxyFactoryCommunicatorEpollObjectProxy与ObjectProxyFactory初始化代码1. 执行stringToProxy2.执行Communicator的初始化函数3.尝试获取ServantProxy4.获取ObjectProxy5.建立ObjectProxy与AdapterProxy的关系6.继续完成Ser

TARSFoundation的博客 3424

wkhtmltopdf 动态页面导出 PDF 全解:三档配方 + 翻车急救避坑指南

周五下班前五分钟,你导出一份季度销售看板 PDF,双击打开——图表全是灰色占位框,表格停在第一页,评论区空空荡荡。同一份页面在浏览器里明明好好的。问题出在:浏览器是"活"的,数据到了就继续渲染;而 wkhtmltopdf 干的活是给页面拍一张一次性照片,按下快门那一刻没渲染完的东西,永远不会出现在 PDF 里。 [![wkhtmltopdf 将动态页面渲染导出为 PDF](https://raw

gitblog_09812的博客 854

微服务开源框架TARS的RPC源码解析 之 初识TARS C++服务端

作者:Cony 导语:微服务开源框架TARS的RPC调用包含客户端与服务端,《微服务开源框架TARS的RPC源码解析》系列文章将从初识客户端、客户端的同步及异步调用、初识服务端、服务端的工作流程四部分,以C++语言为载体,深入浅出地带你了解TARS RPC调用的原理。 什么是TARS TARS是腾讯使用十年的微服务开发框架,目前支持C++、Java、PHP、Node.js、Go语言。该开源项目为用户提供了涉及到开发、运维、以及测试的一整套微服务平台PaaS解决方案,帮助一个产品或者服务快速开发、部署、测试.

TARSFoundation的博客 3883

cpp c++源码实现mcp协议(AI智能体通讯项目的子项目)

它的核心思想是:当 MCP Server 提供大量工具时,不再将所有工具都发送给 LLM,而是通过语义相似度搜索,只返回与用户查询最相关的少量工具。,但是针对mcp协议这个子项目,一直没有从完整项目里摘出来,代码看起来可能比较费事,针对这种情况,今天我把它摘出来了。加入星球福利,后续如果有其他活动、服务,不收费,不收费,可以合理赚钱就收取下星球费用,但是不割韭菜,保持初心。(4)活跃的学习氛围,星球打卡不只是一个形式,而是每天观看,针对同学们的学习情况提出合理化的建议,

weixin_52259848的博客 1141

终极C++ JSON-RPC框架:10分钟快速构建跨平台远程调用系统

想要在C++项目中轻松实现远程过程调用?**libjson-rpc-cpp** 正是你需要的终极解决方案!这个强大的C++ JSON-RPC框架让跨平台远程调用变得简单高效。作为一款专业的JSON-RPC框架,它支持多种传输协议,提供完整的客户端和服务器端实现,让开发者能够专注于业务逻辑而非通信细节。🚀 ## 为什么选择libjson-rpc-cpp? 在分布式系统开发中,**JSON-RP

gitblog_00866的博客 372
上一篇: 【现代C++高效并发】:掌握C++26中std::future的5种结果传递技巧
下一篇: 【稀缺资料】C++26 CPU亲和性底层机制曝光:性能提升40%的秘密
LiteCode
博客等级 码龄1年 146粉丝 2019原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值