前言

最近一直在学习redis,通过c/cpp来执行redis命令,使用的是hiredis客户端来实现的。
先简单贴一下代码

头文件

#include <vector>
#include <string>
#include <hiredis/hiredis.h>
typedef enum en_redisResultType
{redis_reply_invalid = -1,redis_reply_string,redis_reply_integer,redis_reply_array,redis_reply_null
}redisResultType;
typedef struct st_redisResult
{int type;int inter;std::string strdata;std::vector<std::string> vecdata;
}redisResult;
class CRedisBase
{
public:CRedisBase(const char *szip, int port, const char *szpwd, int dbname);CRedisBase(void);~CRedisBase(void);int open_redis();int close_redis();int set_redis(const char *szcmd);int set_redis_datas(std::vector<std::string> vcmd);int get_redis(const char *szcmd, redisResult &result);int get_redis_datas(std::vector<std::string> vcmd, std::vector<redisResult> &vresult);int setConfig(const char *szip, int port, const char *szpwd, int dbname);
private:redisContext *m_redis;std::string m_strip;std::string m_strpasswd;int m_port;int m_db;int free_redis_reply(redisReply *reply);int auth_redis(const char *szpwd);int set_redis_pipeline(std::vector<std::string> vcmd, std::vector<int> &vstatus);int get_redis_pipeline(std::vector<std::string> vcmd, std::vector<redisResult> &vresult);
};

代码

#include "redisbase.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

初始化操作

CRedisBase::CRedisBase(const char *szip, int port, const char *szpwd, int dbname)
{m_redis = NULL;setConfig(szip, port, szpwd, dbname);
}CRedisBase::CRedisBase()
{m_redis = NULL;
}CRedisBase::~CRedisBase(void)
{close_redis();
}int CRedisBase::setConfig(const char *szip, int port, const char *szpwd, int dbname)
{m_strip = szip;m_strpasswd = szpwd;m_port = port;m_db = dbname;return 0;
}

建立redis连接

int CRedisBase::open_redis()
{close_redis();int ret = -1;struct timeval timeout = {1, 500000};// 1.5 secondsfor (int i = 0; i < 10; i ++){m_redis = redisConnectWithTimeout(m_strip.c_str(), m_port, timeout);if (m_redis == NULL || m_redis->err){if (m_redis){printf("connection redis %s:%d error:%s\n", m_strip.c_str(), m_port, m_redis->errstr);close_redis();}else{printf("connection redis %s:%d error:can't allocate redis context\n",m_strip.c_str(), m_port);}sleep(3);}else{if(auth_redis(m_strpasswd.c_str())){close_redis();printf("connection redis %s:%d error: auth error\n", m_strip.c_str(), m_port);}else{printf("connection redis %s:%d success\n", m_strip.c_str(), m_port);char szcmd[64]= {0};snprintf(szcmd,sizeof(szcmd),"select %d", m_db);printf("select db:%d\n", m_db);set_redis(szcmd);ret = 0;break;}}}return ret;
}

认证

int CRedisBase::auth_redis(const char *szpwd)
{int ret = 0;redisReply *reply = (redisReply *)redisCommand(m_redis, "AUTH %s", szpwd);if (reply == NULL){printf("AUTH error\n");return -1;}if (reply->type != REDIS_REPLY_STATUS){printf("AUTH error: type [%d]\n", reply->type);ret = -1;}else{if (strcmp(reply->str, "OK") == 0){printf("AUTH success [%s]\n", reply->str);}else{printf("AUTH error: [%s]\n", reply->str);ret = -1;}}return ret;
}

关闭操作

关闭redis连接

int CRedisBase::close_redis()
{if (m_redis){redisFree(m_redis);m_redis = NULL;}return 0;
}

释放reply

int CRedisBase::free_redis_reply(redisReply *reply)
{if (reply){freeReplyObject(reply);reply = NULL;}return 0;
}

数据操作

hiredis通过redisCommand接口获取数据后,数据保存在redisReply 结构体指针中,通过判断结构体的type成员类型,来获取相对应的数据。
为了防止断线,若redisReply 结构体指针为NULL时,重新连接redis

向redis设置数据

int CRedisBase::set_redis(const char *szcmd)
{if (szcmd == NULL)return -1;if (m_redis == NULL){if (open_redis())return -1;}redisReply *reply = (redisReply *)redisCommand(m_redis, szcmd);if (reply == NULL){close_redis();open_redis();reply = (redisReply *)redisCommand(m_redis, szcmd);if (reply == NULL){printf("exec [%s] error\n", szcmd);return -1;}}//printf("##########################exec [%s]\n", szcmd);int ret = 0;switch(reply->type){case REDIS_REPLY_STATUS:if (strcmp(reply->str, "OK") == 0)ret = 0;elseret = -1;printf("[%s] status [%s]\n", szcmd, reply->str);break;case REDIS_REPLY_ERROR:ret = -1;printf("[%s] error [%s]\n", szcmd, reply->str);break;case REDIS_REPLY_STRING:ret = 0;printf("[%s] set result type:string\n", szcmd);break;case REDIS_REPLY_INTEGER:ret = 0;printf("[%s] set result type:integer:%d\n", szcmd, reply->integer);break;case REDIS_REPLY_ARRAY:ret = 0;printf("[%s] set result type:array\n", szcmd);break;case REDIS_REPLY_NIL:ret = 0;printf("[%s] set result type:null\n", szcmd);break;default:ret = -1;printf("[%s] set error\n", szcmd);break;}free_redis_reply(reply);return ret;
}

向redis获取数据

int CRedisBase::get_redis(const char *szcmd, redisResult &result)
{if (szcmd == NULL)return NULL;if (m_redis == NULL){if (open_redis())return -1;}result.type =  redis_reply_invalid;result.inter = 0;redisReply *reply = (redisReply *)redisCommand(m_redis, szcmd);if (reply == NULL){close_redis();open_redis();reply = (redisReply *)redisCommand(m_redis, szcmd);if (reply == NULL){printf("exec [%s] error\n", szcmd);return -1;}}//printf("##########################exec [%s]\n", szcmd);int ret = 0;switch(reply->type){case REDIS_REPLY_STATUS:ret = -1;printf("[%s] status [%s]\n", szcmd, reply->str);break;case REDIS_REPLY_ERROR:ret = -1;printf("[%s] error [%s]\n", szcmd, reply->str);break;case REDIS_REPLY_STRING:ret = 0;result.type = redis_reply_string;result.strdata = reply->str;printf("[%s] get string\n", szcmd);break;case REDIS_REPLY_INTEGER:ret = 0;result.type = redis_reply_integer;result.inter = reply->integer;printf("[%s] get integer\n", szcmd);break;case REDIS_REPLY_ARRAY:ret = 0;result.type = redis_reply_array;for (int i = 0; i < reply->elements; i ++){result.vecdata.push_back(reply->element[i]->str);}printf("[%s] get array\n", szcmd);break;case REDIS_REPLY_NIL:ret = 0;result.type = redis_reply_null;printf("[%s] get null\n", szcmd);break;default:ret = -1;result.type = redis_reply_invalid;printf("[%s] get error\n", szcmd);break;}free_redis_reply(reply);return ret;
}

通过pipeline批量向redis设置数据

int CRedisBase::set_redis_datas(std::vector<std::string> vcmd)
{std::vector<int> vstatus;if (set_redis_pipeline(vcmd, vstatus)){close_redis();open_redis();if (set_redis_pipeline(vcmd, vstatus)){printf("exec set redises error\n");return -1;}}return 0;
}int CRedisBase::set_redis_pipeline(std::vector<std::string> vcmd, std::vector<int> &vstatus)
{if (vcmd.empty())return 0;if (m_redis == NULL){if (open_redis())return -1;}for (int i = 0; i < vcmd.size(); i ++){redisAppendCommand(m_redis, vcmd[i].c_str());}for (int i = 0; i < vcmd.size(); i ++){int ret = -1;redisReply *reply = NULL;if (redisGetReply(m_redis, (void **)&reply) == REDIS_OK && reply != NULL)if (ret == REDIS_OK && reply != NULL){switch(reply->type){case REDIS_REPLY_STATUS:if (strcmp(reply->str, "OK") == 0)ret = 0;elseret = -1;printf("[%s] status [%s]\n", vcmd[i].c_str(), reply->str);break;case REDIS_REPLY_ERROR:ret = -1;printf("[%s] error [%s]\n", vcmd[i].c_str(), reply->str);break;case REDIS_REPLY_STRING:ret = 0;printf("[%s] set result type:string\n", vcmd[i].c_str());break;case REDIS_REPLY_INTEGER:ret = 0;printf("[%s] set result type:integer:%d\n", vcmd[i].c_str(), reply->integer);break;case REDIS_REPLY_ARRAY:ret = 0;printf("[%s] set result type:array\n", vcmd[i].c_str());break;case REDIS_REPLY_NIL:ret = 0;printf("[%s] set result type:null\n", vcmd[i].c_str());break;default:ret = -1;printf("[%s] set error\n", vcmd[i].c_str());break;}}else{freeReplyObject(reply);reply = NULL;return -1;}freeReplyObject(reply);reply = NULL;vstatus.push_back(ret);}return 0;
}

通过pipeline批量获取数据

int CRedisBase::get_redis_datas(std::vector<std::string> vcmd, std::vector<redisResult> &vresult)
{if (get_redis_pipeline(vcmd, vresult)){close_redis();open_redis();if (get_redis_pipeline(vcmd, vresult)){printf("exec get redises error\n");return -1;}}return 0;
}int CRedisBase::get_redis_pipeline(std::vector<std::string> vcmd, std::vector<redisResult> &vresult)
{if (vcmd.empty())return -1;if (m_redis == NULL){if (open_redis())return -1;}for (int i = 0; i < vcmd.size(); i ++){redisAppendCommand(m_redis, vcmd[i].c_str());}for (int i = 0; i < vcmd.size(); i ++){int ret = -1;redisResult result;result.type =  redis_reply_invalid;result.inter = 0;redisReply *reply = NULL;if (redisGetReply(m_redis, (void **)&reply) == REDIS_OK && reply != NULL){switch(reply->type){case REDIS_REPLY_STATUS:if (strcmp(reply->str, "OK") == 0)ret = 0;elseret = -1;printf("[%s] status [%s]\n", vcmd[i].c_str(), reply->str);break;case REDIS_REPLY_ERROR:ret = -1;printf("[%s] error [%s]\n", vcmd[i].c_str(), reply->str);break;case REDIS_REPLY_STRING:ret = 0;result.type = redis_reply_string;result.strdata = reply->str;printf("[%s] get string\n", vcmd[i].c_str());break;case REDIS_REPLY_INTEGER:ret = 0;result.type = redis_reply_integer;result.inter = reply->integer;printf("[%s] get integer\n", vcmd[i].c_str());break;case REDIS_REPLY_ARRAY:ret = 0;result.type = redis_reply_array;for (int i = 0; i < reply->elements; i ++){result.vecdata.push_back(reply->element[i]->str);}printf("[%s] get array\n", vcmd[i].c_str());break;case REDIS_REPLY_NIL:ret = 0;result.type = redis_reply_null;printf("[%s] get null\n", vcmd[i].c_str());break;default:ret = -1;result.type = redis_reply_invalid;printf("[%s] get error\n", vcmd[i].c_str());break;}}else{freeReplyObject(reply);reply = NULL;return -1;}freeReplyObject(reply);reply = NULL;vresult.push_back(result);}return 0;
}

参考文章

封装hiredis
redis 使用-hiredis库使用

转载于:https://www.cnblogs.com/JesseTsou/p/10418439.html

【redis】c/c++操作redis(对于hiredis的封装)相关推荐

  1. Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅)

    Spring Boot 整合Redis 包含Java操作Redis哨兵 作者:哇塞大嘴好帥(哇塞大嘴好帅) 1. 配置环境 在SpringBoot2.0版本以后,原来使用的jedis被替换成为了let ...

  2. 【redis】java操作redis时,StringRedisTemplate的expire()方法的作用,什么时候使用

    java操作redis时,StringRedisTemplate的expire()方法的作用,什么时候使用 //重新设置过期时间为30分钟,刷新时间 redisTemplate.expire(MsOp ...

  3. linux 安装了redis,Linux安装操作redis

    安装redis 环境准备:yum install gcc-c++,gcc环境 上传解压redis安装包 安装redis,进入解压目录,输入make命令进行安装. 安装注意事项: 如果没有gcc环境,安 ...

  4. Redis缓存 ava-Jedis操作Redis,基本操作以及 实现对象保存

    源代码下载: http://download.csdn.net/detail/jiangtao_st/7623113 1.Maven配置 [html] view plaincopyprint? < ...

  5. redis的lrange_thinkphp5操作redis系列教程】列表类型之lRange,lGetRange

    namespace app\admin\controller; use think\cache\driver\Redis; use think\Controller; use \think\Db; c ...

  6. Redis-Linux中安装Redis、命令操作Redis

    目录 一.Redis简介 NoSQL与SQL的区别 二.Linux上安装redis 上传并解压redis.gz 进入 redis的解压目录,执行命令 make ​编辑 修改redis为守护进程 们测试 ...

  7. Python操作redis(普通操作,连接池,封装)

    安装python包 pip install redis==2.10.6 普通操作 import redisabc = {"aa":{"bb":"cc& ...

  8. Redis——使用 python 操作 redis 之从 hmse 迁移到 hset

    环境 windows 10 专业版 pycharm pro python 3.7 redis library 4.1.4 补充:Windows redis 3.2.100 问题描述 我想向一个 has ...

  9. Java操作Redis(四)--Java操作Redis实现排行榜

    应用说明 package com.ruoyi.project.redis;import redis.clients.jedis.Jedis; import redis.clients.jedis.Tu ...

  10. java jedis使用_Java中使用Jedis操作Redis

    Java中使用Jedis操作Redis 使用Java操作Redis需要jedis-2.1.0.jar,下载地址:http://files.cnblogs.com/liuling/jedis-2.1.0 ...

最新文章

  1. Oracle数据库空间管理
  2. ECSHOP二次开发文档【文件结构和数据库表分析】
  3. 使用Tkinter的Label组件写一个广告板招租
  4. Intel Idea导入eclipse下的web项目并部署到tomcat
  5. 微软的正则表达式教程(一):正则表达式简介
  6. 大一萌新看过来,C语言学到什么程度,才能“毕业不失业”!
  7. “操作系统不以 C 开头和结尾,C 不等于整个世界”
  8. Linux scp 使用详解
  9. 20200612每日一句
  10. Visual Studio添加图片资源到exe
  11. 视频教程-Dubbo视频教程-Java
  12. 浅分享一下zzulioj刷题总结
  13. linux在当前目录 查找abc文件夹,《find技巧》-“linux命令五分系列”之一
  14. redis从入门到入魔
  15. 芯片自主注释流程代码
  16. 英语词根词缀记忆大全
  17. bitcoin core全节点钱包同步太慢的解决方法及钱包数据文件移动的方法
  18. OpenEuler树莓派基础实验 20212802范辰宇
  19. 多语言 - 国际化处理 上
  20. python 服务端渲染_客户端渲染与服务端渲染

热门文章

  1. 开源库BearSSL介绍及使用
  2. C++中前置声明介绍
  3. 【C++】智能指针(一)入门
  4. java 安装界面广告_用javascript实现仿163的js广告向下挤压页面的效果
  5. android首页图片轮播效果,Android_Android自动播放Banner图片轮播效果,先看一下效果图支持本地图 - phpStudy...
  6. 安卓饼状图设置软件_话单及银行卡交易智能分析软件
  7. c语言中二进制用什么字母表示方法,看C语言编码转换--------负数的二进制表示方法...
  8. webgl 游戏_30个令人惊叹的WebGL示例和演示
  9. 【js】内置对象String的常用方法
  10. mysql ltree_mysq基础知识总结l