c++ centos redis 通讯demo 封装

Posted 小城熊儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++ centos redis 通讯demo 封装相关的知识,希望对你有一定的参考价值。

c++ redis 通讯,可以使用hiredis api开发,

先安装 redis  和 hiredis

# 安装redis
# 需要安装Remi的软件源,# 另一种方案  https://blog.csdn.net/WeiHao0240/article/details/116455608?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum --enablerepo=remi install redis -y
rpm -ql redis
rpm -qa |grep redis
redis-server -v

# c++ 使用redis ,(git,版本大于2,使用默认源下载的git无法正常clone)需要hiredis  编译时加上 -lhiredis eg:g++  main.cpp MyDB.cpp -o main -lhiredis  `mysql_config --cflags --libs` 
# 源码安装 git 参考 https://www.cnblogs.com/todarcy/p/11050337.html
yum install -y http://opensource.wandisco.com/centos/6/git/x86_64/wandisco-git-release-6-1.noarch.rpm
yum install git -y
git --version
git clone https://github.com/redis/hiredis
cd hiredis
make
sudo make install        # 复制生成的库到/usr/local/lib目录下
sudo ldconfig /usr/local/lib

 

 

记录下常用的redis指令

# redis 常用命令(版本高一点,可以一次插入多个值)
# service redis start            # 启动redis
# service redis stop             # 停止redis
# service redis status             # 查看redis运行状态
# ps -ef | grep redis            # 查看redis进程

# chkconfig redis on            # 设置redis为开机自动启动
# vi /etc/redis.conf            # 修改redis默认端口和密码        
# 修改第80行 901行 参考 https://www.cnblogs.com/chengxs/p/9833911.html    https://blog.csdn.net/WeiHao0240/article/details/116455608?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
# redis-server /etc/redis.conf &     # 使用配置文件启动redis
# redis-cli -h 127.0.0.1 -p 6379    # 使用端口登录,输入redis密码 redis_pwd       # redis-cli                    # 进入本机redis
# auth redis_pwd

# 远程连接参考 https://www.jianshu.com/p/6895384d2b9e
# 常用命令参考 https://www.cnblogs.com/cxxjohnson/p/9072383.html
# Redis Desktop Manager 下载  https://pan.baidu.com/s/1Jvr9MbgFn4UJh4M1AMo3gA 提取码:3i9b

# key
#     keys * 获取所有的key
#     select 0 选择第一个库
#     move myString 1 将当前的数据库key移动到某个数据库,目标库有,则不能移动
#     flush db      清除指定库
#     randomkey     随机key
#     type key      类型   
#     set key1 value1 设置key
#     get key1    获取key
#     mset key1 value1 key2 value2 key3 value3
#     mget key1 key2 key3
#     del key1   删除key
#     exists key      判断是否存在key
#     expire key 10   10过期
#     pexpire key 1000 毫秒
#     persist key     删除过期时间
    
# hash
#     hset myhash name cxx
#     hget myhash name
#     hmset myhash name cxx age 25 note "i am notes"
#     hmget myhash name age note   
#     hgetall myhash               获取所有的
#     hexists myhash name          是否存在
#     hsetnx myhash score 100      设置不存在的
#     hincrby myhash id 1          递增
#     hdel myhash name             删除
#     hkeys myhash                 只取key
#     hvals myhash                 只取value
#     hlen myhash                  长度

# set
#     sadd myset redis 
#     smembers myset       数据集合
#     srem myset set1         删除
#     sismember myset set1 判断元素是否在集合中
#     scard key_name       个数
#     sdiff | sinter | sunion 操作:集合间运算:差集 | 交集 | 并集
#     srandmember          随机获取集合中的元素
#     spop                 从集合中弹出一个元素

    
# Redis本身存储就是一个hash表,     Key只有String类型 Value包括String ,Set,List,Hash,Zset五中类型
# 对于用户设备 对应关系来说,  key  使用 username 和 deviceid  (都属于唯一值)    ,value 存放采用 set 类型
# 对于设备基本信息 key deviceid      ,value使用 Hash 类型  ,ip:port(frontTcp)  header  key  protocolVersion  keyVersion

# c++操作 redis 使用的是 hiredis
# 返回值是一个类型,判断type,决定读取哪一个数据
# typedef struct redisReply {
#     int type; /* 返回值类型 */
#     long long integer; /* 当返回类型为 REDIS_REPLY_INTEGER 时 */
#     size_t len; /* 返回的字符串长度 */
#     char *str; /* 当返回值类型为 REDIS_REPLY_ERROR 和 REDIS_REPLY_STRING */
#     size_t elements; /* 返回的数组长度 */
#     struct redisReply **element; /* 当返回值类型为 REDIS_REPLY_ARRAY */
# } redisReply;
# type 有以下几种类型:
#   REDIS_REPLY_STRING  : 1 
#   REDIS_REPLY_ARRAY : 2
#   REDIS_REPLY_INTEGER :3 
#   REDIS_REPLY_NIL  : 4
#   REDIS_REPLY_STATUS : 5
#   REDIS_REPLY_ERROR : 6

 

 

源文件

MyRedis.h

/*************************************************************************
> File Name: MyRedis.h
> Author:Ashuai 
> Mail:2829735186@qq.com 
> Created Time: 2021年05月20日 星期三 11时11分11秒
************************************************************************/

#ifndef _MYREDIS_H
#define _MYREDIS_H

#include <stdio.h> 
#include <stdlib.h> 
#include <stddef.h> 
#include <stdarg.h> 
#include <string.h> 
#include <assert.h> 
#include <hiredis/hiredis.h> 

using namespace std;

class MyRedis
{
    public:
        MyRedis();
        ~MyRedis();
        bool initRedis(string host="127.0.0.1",int port=6379,string passwd=""); //连接mysql
        bool exeSQL(string sql);   //执行sql语句
        bool freeResult();      //释放查询结果内存
        void showResult(redisReply *result);      //展示结果
    public:
        redisReply *result;      //指向查询结果的指针

    private:
        redisContext *conn;           //连接redis句柄指针
        
};


#endif


// //测试 demo  main.cpp  编译     g++  main.cpp MyRedis.cpp -o main -lhiredis     
// #include<iostream>
// #include"MyRedis.h"
// using namespace std;
// int main()
// {
//     MyRedis redis;
//     bool init = redis.initRedis("127.0.0.1",6379,"authPassword");
//     cout<<endl;
//     // if(init==false) redis.exeSQL("auth authPassword");
//     cout<<"command:"<<"hget 0000000000000102 ip"<<endl;
//     if(redis.exeSQL("hget 0000000000000102 ip") && redis.result ){
//         redis.showResult(redis.result);
//     }
//     redis.freeResult();cout<<endl;

//     cout<<"command:"<<"hgetall 0000000000000101"<<endl;
//     if(redis.exeSQL("hgetall 0000000000000101") && redis.result ){
//         redis.showResult(redis.result);
//     }
//     redis.freeResult();cout<<endl;

//     cout<<"command:"<<"keys *"<<endl;
//     if(redis.exeSQL("keys *") && redis.result ){
//         redis.showResult(redis.result);
//     }
//     redis.freeResult();

//     cout<<endl<<endl<<endl;
//     return 0;
// }

 

MyRedis.cpp

 

/*************************************************************************
> File Name: MyRedis.cpp
> Author:Ashuai 
> Mail:2829735186@qq.com 
> Created Time: 2021年05月20日 星期三 11时11分11秒
************************************************************************/

#include<iostream>
#include<string>
#include "MyRedis.h"

using namespace std;

MyRedis::MyRedis(){ }

MyRedis::~MyRedis()
{
    if (result) freeReplyObject(result);
    if(conn!=NULL)  //关闭连接
    {
        redisFree(conn); 
    }
}


bool MyRedis::initRedis(string host,int port,string passwd)
{
    conn = redisConnect(host.c_str(), port); 
    if ( conn->err) 
    { 
        redisFree(conn); 
        printf("Connect to redisServer faile\\n"); 
        exit(1);   
    } 
    
    if(sizeof(passwd)>0)
    {
        string auth("auth ");
        auth.append(passwd);
        result = (redisReply*)redisCommand(conn, auth.c_str());   //auth 执行成功后返回 ok
        if( NULL == result) 
        { 
            printf("Execut auth failure\\n");  
            return false; 
        }
        if( !(result->type == REDIS_REPLY_STATUS && strcasecmp(result->str,"OK")==0)) 
        { 
            printf("Execut auth failure\\n");  
            return false; 
        }
        printf("redisServer auth Success\\n");  
        freeReplyObject(result);
    }
    printf("Connect to redisServer Success\\n");  
    return true;  
}

bool MyRedis::exeSQL(string sql)
{
    result = (redisReply*)redisCommand(conn, sql.c_str()); 
       
    if( NULL == result) 
    { 
        printf("Execut command failure\\n");  
        return false; 
    }
    if(result->type == REDIS_REPLY_ERROR) 
    { 
        printf("Execut REDIS_REPLY_ERROR \\n");  
        freeResult();
        return false; 
    }
    return true;
}

// 释放结果集的内存
bool MyRedis::freeResult(){
    if (result) {
        freeReplyObject(result);
        result = NULL;
    }
    return true;
}

void MyRedis::showResult(redisReply *result){


    switch(result->type){
        case REDIS_REPLY_STRING:{
            cout<<"REDIS_REPLY_STRING :"<<result->str << endl;
            break;
        }
        case REDIS_REPLY_ARRAY:{
            //此处 不排除套娃现象
            // struct redisReply **v = result->element;
            for(int i=0;i<result->elements;i++)
            {
                showResult(result->element[i]);
            }
            break;
        }
        case REDIS_REPLY_INTEGER:{
            cout<<"REDIS_REPLY_INTEGER :"<<result->integer<< endl;
            break;
        }
        case REDIS_REPLY_NIL:{
            cout<<"REDIS_REPLY_NIL :"<<result->str<< endl;
            break;
        }
        case REDIS_REPLY_STATUS:{
            cout<<"REDIS_REPLY_STATUS :"<<result->str<<endl;
            break;
        }
        case REDIS_REPLY_ERROR:{
            cout<<"REDIS_REPLY_ERROR :"<<result->str<< endl;
            break;
        }
        default:break;
    }
}

 

 

 

 

 

//

以上是关于c++ centos redis 通讯demo 封装的主要内容,如果未能解决你的问题,请参考以下文章

使用 PHP 发送 1and1 到 2k 封不同电子邮件的时事通讯

CentoS 7系统安装redis教程

CentoS 7系统安装redis教程

玩爬虫封IP是最头痛的事情!从零搭建异步爬虫代理池!随你怎么封

从 C# 调用 C++ dll。 “无法封送'返回值':托管/非托管类型组合无效。”

咸鱼教程protobuf在websocket通讯中的使用