Linux下C++操作redis简述

本文介绍如何在Linux环境下使用C++操作Redis,涵盖建立连接、执行命令及结果处理等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis是基于内存的高性能key-value存储系统,是在实际项目中常用来作为缓存,队列,数据库来使用。本文主要介绍在Linux环境下如何使用C++作为客户端操作Redis。
C++中使用redis需要包含以下头文件

#include <hiredis/hiredis.h>

下面将从建立redis链接的对象redisContext和执行redis命令的返回对象redisReply说起。让我们从源码hiredis/hiredis.h开始吧。

redisContext是建立redis链接返回的上下文信息

typedef struct redisContext 
{
    int err; //链接错误的标志位,当正确链接时,该值为0
    char errstr[128]; //链接错误时的错误描述
    int fd; //正确链接时,返回的句柄,用于以后的命令执行等
    int flags; //状态位 如REDIS_BLOCK...
    char *obuf; //写缓冲区
    //协议解析的状态,具体见redisReader定义,由于建立链接的协议解析是内部进行的
    //没有暴露给外部使用,在此,不进行累述
    redisReader *reader; 
} redisContext;

当建立链接后,我们可以借助redisContext信息,判断链接是否成功了,以及实时监测当前的链接状态。
redis建立链接的方式有多种:

redisContext *redisConnect(const char *ip, int port);
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
redisContext *redisConnectNonBlock(const char *ip, int port);
redisContext *redisConnectBindNonBlock(const char *ip, int port, const char *source_addr);
.....

常见的链接方式是前两种,redisConnectWithTimeout()相对于redisConnect()提供超时链接功能。
struct timeval 定义在

#include <sys/time.h>

提供了微秒级的精度的时间操作。

struct timeval
{
    time_t tv_sec; //秒
    suseconds_t tv_usec;//微秒
};

redisReply,redis命令执行后的返回对象

typedef struct redisReply 
{
    /*
     *返回值的类型
     *#define REDIS_REPLY_STRING 1
     *#define REDIS_REPLY_ARRAY 2
     *#define REDIS_REPLY_INTEGER 3
     *#define REDIS_REPLY_NIL 4
     *#define REDIS_REPLY_STATUS 5
     *#define REDIS_REPLY_ERROR 6
     */
    int type; //返回值的类型 
    long long integer;  //当返回值是整数时,对应的整数值
    int len;   //返回string值时,string值的长度
    /*
     *当返回类型是REDIS_REPLY_ERROR时,str是error的内容
     *但返回类型是REDIS_REPLY_STRING时,str是string值的内容
     */
    char *str; 
    //当返回类型是 REDIS_REPLY_ARRAY时,返回值的个数
    size_t elements; 
    //当返回类型是 REDIS_REPLY_ARRAY时,对应的返回值‘数组’
    struct redisReply **element; 
} redisReply;

根据redis是C编写的,内存构造都是通过C的方式,由redisReply数据结构也可看出,每次执行命令后,不会自动析构返回值对象,我们应该及时的使用freeReplyObject释放对象,以免对下次执行结果造成影响。
此外,redisReply对象的返回值类型type是什么,取决于执行的命令,如果不知道,不妨通过shell执行下该命令,观察下状态

例如,当获取一个不存在的键值时,返回nil
127.0.0.1:6379> GET noexists
(nil)
当正确向有序集合加入键值对时,返回正确插入DB中的键值对个数
127.0.0.1:6379> ZADD students 16 Lilei
(integer) 1
当正确从string类型取值时,返回的是string
127.0.0.1:6379> get name
"Xiaoming"
...

C++执行redis语句的方式

void *redisvCommand(redisContext *c, const char *format, va_list ap);
void *redisCommand(redisContext *c, const char *format, ...);
具体将在示例中予以演示

下面以一个简单的示例,回顾下以上所述吧,本文redis版本为3.2.4,编译环境为“CentOS release 5.5 (Final)”。

#include <iostream>
#include <string>
//for C++ redis
#include <hiredis/hiredis.h>

using namespace std;

int main()
{
    //使用本地地址和默认端口号
    string strHost = "127.0.0.1";
    int nPort = 6379;
    //connect
    redisContext *connect;
    connect = redisConnect(strHost.c_str(),nPort);
    if(NULL == connect)
    {
        cout<<__LINE__<<"Connect failed..."<<endl;
        return -1;
    }
    //进一步检查连接的状态
    if(connect->err)
    {
        //connect->errstr错误描述
        cout<<__LINE__<<"Connect err"<<connect->errstr<<endl;
        redisFree(connect);
        return -1;
    }
    //向redis写入数据
    //使用有序集合,向其中加入 姓名-年龄的键值对
    redisReply *reply;
    //方式一
    string strcmd = "ZADD students 16 Lilei";
    reply = (redisReply *) redisCommand(connect, strcmd.c_str());
    if(NULL == reply)
    {
        cout<<__LINE__<<"Write to redis failed..."<<endl;
        return -1;
    }
    //如正确执行,返回值类型应为成功插入数据库键值对个数,是一个整数
    if(REDIS_REPLY_INTEGER != reply->type)
    {
        cout<<__LINE__<<"Execute failed..."<<endl;
        freeReplyObject(reply);
        return -1;
    }
    //释放上次执行的结果
    freeReplyObject(reply);
    //方式二
    reply = (redisReply *) redisCommand(connect, "ZADD %s %d %s","students",15,"Hanmeimei");
    if(NULL == reply)
    {
        cout<<__LINE__<<"Write to redis failed..."<<endl;
        return -1;
    }
    //如正确执行,返回值类型应为成功插入数据库键值对个数,是一个整数
    if(REDIS_REPLY_INTEGER != reply->type)
    {
        cout<<__LINE__<<"Execute failed..."<<endl;
        freeReplyObject(reply);
        return -1;
    }
    //释放上次执行的结果
    freeReplyObject(reply);

    //查询
    strcmd = "ZRANGE students 0 -1 WITHSCORES";
    reply = (redisReply *) redisCommand(connect, strcmd.c_str());
    if(NULL == reply)
    {
        cout<<__LINE__<<"Write to redis failed..."<<endl;
        return -1;
    }
    for(size_t i = 0 ; i < reply->elements ;++i)
    {
        //为什么是如下的输出方式,动手通过shell执行下 ZRANGE students 0 -1 WITHSCORES 吧
        //实际上其返回值是
        /*
        127.0.0.1:6379> ZRANGE students 0 -1 WITHSCORES
        1) "Hanmeimei"
        2) "15"
        3) "Lilei"
        4) "16"
        */
        string name = reply->element[i]->str ;
        string age = reply->element[++i]->str ;

        cout<<name<<":"<<age<<endl;
    }
    freeReplyObject(reply);

    redisFree(connect);
    return 0;
}

编译时请链接所需的库libhiredis,执行:
[root@localhost redis]# ./run
Hanmeimei:15
Lilei:16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值