linux c 封装redis,封装hiredis——C++与redis对接(一)(string的SET与GET操作)

redis,总想着像Mysql一样,在C/C++中进行对接。于是查询了一些资料,最后找到了hiredis。然而直接用它的话,难免有点不方便。于是,对其进行封装。

hiredis直接去git上克隆,地址:https://github.com/redis/hiredis。

下载好之后,由于其自带Makefile,只要make一下就编译出静态库与动态库了,接着把头文件和静/动态库放在相应的文件夹里就可以了。注意如果使用动态库,而且是放在/usr/local/lib/里,得执行ldconfig命令,来更新一下配置,或者得配置一下动态库路径。

安装好了就是如何使用的事了。

学习hiredis主要是参考这两个链接:

http://blog.csdn.net/gqtcgq/article/details/51344232

http://blog.csdn.net/achelloworld/article/details/41598389?utm_source=tuicool&utm_medium=referral

文章给大家分享C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK技术,面试技巧方面的资料分享的https://ke.qq.com/course/417774?flowToken=1011069

一共就五个函数。

1、redisContext* redisConnect(const char *ip, int port)2、redisContext* redisConnectWithTimeout(const char *ip, int port, timeval tv)3、void redisFree(redisContext *c)4、void *redisCommand(redisContext *c, const char *format...)5、void freeReplyObject(void *reply)

和Mysql一样,要对接,第一件事就是用IP和端口号建立连接什么的。redis的端口号一般是6379,IP直接用127.0.0.1就可以了。既然要用到IP和端口号,又是可能会变的东西,为了不使想要改变它们的时候得直接修改代码,我写了个配置文件:

redisConf.json

1 {

2    "IP" : "127.0.0.1" ,

3    "PORT" : 6379

4 }

相应地,有提取配置信息的类

redisConf.h

1 #ifndef __REDISCONF_H__

2 #define __REDISCONF_H__

3 #include

4 namespace ccx{

5 using std::string;

6 class RedisConf

7 {

8    public:

9        RedisConf();

10        void getConf();

11        string getIP();

12        int getPort();

13    private:

14        string _ip;

15        int _port;

16 };

17 }

18 #endif

redisconf.cc

1 #include "redisConf.h"

2 #include

3 #include

4 #include

5 #include

6 #include

7

8 namespace ccx{

9

10 using std::ifstream;

11 using std::cout;

12 using std::endl;

13

14 RedisConf::RedisConf()

15 {

16    getConf();

17 }

18

19 void RedisConf::getConf()

20 {

21    ifstream ifs;

22    ifs.open("redisConf.json");

23    if(!ifs.good())

24    {

25        cout << "open RedisConf.json error" << endl;

26        exit(EXIT_FAILURE);

27    }

28

29    Json::Value root;

30    Json::Reader reader;

31    if(!reader.parse(ifs, root, false))

32    {

33        cout << "RedisConf json reader error" << endl;

34        exit(EXIT_FAILURE);

35    }

36

37    _ip = root["IP"].asString();

38    _port = root["PORT"].asInt();

39    ifs.close();

40 }

41

42 string RedisConf::getIP()

43 {

44    return _ip;

45 }

46

47 int RedisConf::getPort()

48 {

49    return _port;

50 }

51

52 }

然后是目前的redis类:

redis.h

1 #ifndef __REDIS_H__

2 #define __REDIS_H__

3

4 #include "redisConf.h"

5

6 #include

7

8

9 namespace ccx{

10

11 class Redis

12 {

13    public:

14        Redis();

15    public:

16        void Connect();

17        void disConnect();

18    public:

19        void setString(const string & key, const string & value);

20        void setString(const string & key, const int & value);

21        void setString(const string & key, const float & value);

22    private:

23        void setString(const string & data);

24    public:

25        void getString(const string & key, string & value);

26        void getString(const string & key, int & value);

27        void getString(const string & key, float & value);

28    private:

29        void getString(const string & key);

30    private:

31        void freeReply();

32        bool isError();

33    private:

34        RedisConf _conf;

35        redisContext * _context;

36        redisReply * _reply;

37 };

38 }

39

40 #endif下面结合写好的代码说说前面的五个函数。

函数1是用来连接redis的,具体如下:1 void Redis::Connect()

2 {

3    _context = ::redisConnect(_conf.getIP().c_str(), _conf.getPort());

4    cout << _conf.getIP() << "-" << _conf.getPort() << endl;

5    if(_context && _context->err)

6    {

7        cout << "connect redis error" << endl;

8        exit(EXIT_FAILURE);

9    }

10    cout << "redis Connect success" << endl;

11 }

函数2是在1的基础上,添加了一个超时功能。

函数3是在不使用redis了,要断开连接时使用的:

1 void Redis::disConnect()

2 {

3    ::redisFree(_context);

4    cout << "redis disConnect success" << endl;

5 }

函数4稍微复杂一些,有点像C中的printf:

1 printf("%d%s%d",d1,s1,d2);

2 printf("hello,world");

可以这样用:

1 char * command = "SET name lili";

2 reply = (redisReply*)::redisCommand(context, command);

3 char * s1 = "name";

4 char * s2 = "lili";

5 reply = (redisReply*)::redisCommand(context, "SET %s %s", s1, s2);

6 reply = (redisReply*)::redisCommand(context, "SET name lili");

7 ...

第一个参数context是函数1或者2的返回值,告诉它要与哪里的redis进行交互。reply指向命令结果的存储位置。

函数5是用来清理函数4 的返回结果的:

1 void Redis::freeReply()

2 {

3    if(_reply)

4    {

5        ::freeReplyObject(_reply);

6        _reply = NULL;

7    }

8 }

第6行是因为对这个函数不熟,就干脆清完之后给它赋值NULL。

由于redis的string中存的可能是字符串、整形、浮点数,于是各自重载了三个版本的get与set方法,并重用一些函数,以减少代码量。

对于set,直接用一个宏替换:

1 #define SETSTRING(key, value) \

2    stringstream ss;\

3    ss << "SET " << key << " " << value;\

4    string s;\

5    getline(ss, s);\

6    setString(s);

1 void Redis::setString(const string & key, const string & value)

2 {

3    SETSTRING(key, value);

4 }

5 void Redis::setString(const string & key, const int & value)

6 {

7    SETSTRING(key, value);

8 }

9 void Redis::setString(const string & key, const float & value)

10 {

11    SETSTRING(key, value);

12 }

使用C++中的stringstream,会比用“%d”、“%s”、“%f”来区分类型少些代码。两种方法的结果是相同的。

它们共用的setString方法:

1 void Redis::setString(const string & data)

2 {

3    freeReply();

4    _reply = (redisReply*)::redisCommand(_context, data.c_str());

5    if(!isError())

6    {

7        if (!(_reply->type == REDIS_REPLY_STATUS && strcasecmp(_reply->str,"OK") == 0))

8        {

9            cout << "Failed to execute SET(string)" << endl;

10        }

11    }

12 }

这里的isError是用来判断是否连接异常的:

1 bool Redis::isError()

2 {

3    if(NULL == _reply)

4    {

5        freeReply();

6        disConnect();

7        Connect();

8        return true;

9    }

10    return false;

11 }

如果连接异常,得断开重连。

在redis命令行里,如果set成功,会提示“OK”。于是,这里先判断了一下命令结果的数据类型,如果是字符串,再判断它是不是“OK”,以此来判断set是否成功。

对于get,我试了各种方法,都无法直接从命令结果中提取出数字,暂时还没找到原因。但是数字却可以以字符串格式得到。于是,使用了atoi来处理:

1 void Redis::getString(const string & key)

2 {

3    freeReply();

4    _reply = (redisReply*)::redisCommand(_context, "GET %s", key.c_str());

5 }

6

7 void Redis::getString(const string & key, string & value)

8 {

9    getString(key);

10    if(!isError() && _reply->type == REDIS_REPLY_STRING)

11    {

12        value = _reply->str;

13    }

14 }

15

16 void Redis::getString(const string & key, int & value)

17 {

18    getString(key);

19    if(!isError() && _reply->type == REDIS_REPLY_STRING)

20    {

21        value = ::atoi(_reply->str);

22    }

23 }

24

25 void Redis::getString(const string & key, float & value)

26 {

27    getString(key);

28    if(!isError() && _reply->type == REDIS_REPLY_STRING)

29    {

30        value = ::atof(_reply->str);

31    }

32 }

redis.cc

View Code

test.cc

View Code

测试结果如下:

127.0.0.1-6379

redis Connect success

lii

30

30

redis disConnect success

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/563579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win8关闭uefi+linux,UEFI启动是什么?Win8关闭UEFI引导方式的方法

UEFI启动是什么?不少新电脑都给用户直接预装了Win8系统&#xff0c;后来使用又非常不习惯&#xff0c;因此想改成Win7系统&#xff0c;但是在换系统之前&#xff0c;需要在BIOS下关闭UEFI引导方式&#xff0c;可能很多朋友都不懂该如何关闭UEFI启动项。针对这个问题&#xff0…

C语言求x和y的乘积,计算方程式,求x,C语言中怎么计算x,y的值?

导航&#xff1a;网站首页 >计算方程式,求x,C语言中怎么计算x,y的值&#xff1f;计算方程式,求x,C语言中怎么计算x,y的值&#xff1f;匿名网友:(x-1)0吧&#xff0c;写题也这么不仔细呀。哈哈m/xn/(x-1)因为mn≠0&#xff0c;所以m≠0;n≠0&#xff1b;所以方程两边取倒数得…

c语言的单行注释范围,c语言中的注释,multi-line comment

在C/C语言中&#xff0c;在对源文件做预处理的时候&#xff0c;有两条基本原则&#xff1a;1、凡是以//开头的为单行注释2、凡是以\结尾的代表此行尚未结束于是预处理器在处理的时候会先按第二条规则&#xff0c;看每行的末尾的那个字符是不是”\”,是的话&#xff0c;就下一行…

c语言自动拷贝u盘文件,写了一个偷偷拷贝老师U盘所有文件的程序……蛋疼……………...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼直接双击运行&#xff0c;程序会每一秒检查一下是否有移动盘插入&#xff0c;如果有&#xff0c;就在C盘下新建一个文件夹copy&#xff0c;并把移动盘内所有的文件拷贝到C:\copy下。拷贝完成后自动退出。我想也没哪个老师会蛋疼的去…

android listview自动加载更多,如何实现 Android ListView『上拉加载更多』?

ListView上拉加载更多的UI需求(1)向上滑动 ListView&#xff0c;当最后一个条目滚入屏幕时开始加载更多条目&#xff0c;在列表底部增加一个 footerView&#xff1a;一个 infinite progressBar&#xff0c;一个 textView 显示 “Loading...”&#xff1b;(2)根据数据加载的结果…

android webview 字体 系统字体大小,Android 系统字体大小动态改变,导致webview中显示不兼容的问题解决...

唠叨几句&#xff1a;在移动端再开发的过程中&#xff0c;很容易使用到webview,它也是用来混合开发的中间桥梁&#xff0c;因此解决webview使用过程中出现的问题是非常有必要的&#xff1b;问题现象与发现&#xff1a;现象&#xff1a;日前&#xff0c;在是使用webview加载html…

android安全性发展,Android未来发展 安全是重点

自2008年首部Android手机问世以来&#xff0c;谷歌智能手机方面的发展也开始高歌勇进&#xff0c;经过近8年的发展&#xff0c;Android已经成为市场上最大的移动互联网操作系统&#xff0c;市场占有率位居第一&#xff0c;虽然其竞争对手iOS步步紧逼&#xff0c;但是由于Androi…

android 字符串调用方法名,AndroidJNI.CallStringMethod 调用字符串方法

AndroidJNI.CallStringMethod 调用字符串方法static function CallStringMethod (obj : IntPtr, methodID : IntPtr, args : jvalue[]) : stringDescription描述Calls an instance (nonstatic) Java method defined by methodID, optionally passing an array of arguments (ar…

android 服务器返回302,Android WebView 内处理302重定向不跳转的解决

最近项目中Webview加载第三方的具有302的重定向&#xff0c;但是却发现却没有重新跳转。最后发现问题如下&#xff1a;public boolean shouldOverrideUrlLoading(WebView view, String url) {super.shouldOverrideUrlLoading(view, url);.................return true&#xff…

c语言输入一个数求因数,【代码】求一个数的因数和、求优化、顺便也供新人参考算法...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include#includemain(){int n,q,p,m,k1,sum0,s[99999]{2},t[99999];//n是输入的数;q和p分别代表两个数组的工作下标scanf("%d",&n); //k是用来取小于n数的数组工作下标for(int i3;i<n;i2) //去所有小于n的数&…

android手机rom简单制作教程,【图片】ROM助手:任意安卓机型的ROM制作教程【a298t吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼很多机友都在求精简系统&#xff0c;求ROOT等等....但不会怎么办&#xff1f;我来告诉大家一个完美无缺的办法&#xff01;授人以鱼不如授人以渔......蘑菇ROM助手&#xff1b;点击系统精简&#xff0c;导入刷机包。之后我们可以看…

android 邮件分享链接,Android应用从通过电子邮件发送的链接打开

我们的用户不时收到电子邮件.更改密码当他们点击链接时,我想将它们发送到我们的网站,但我们的Android应用程序被打开.链接例如是https://www.ourdomain.com/change-password/{random-string}.我们的应用程序中已经启用了深层链接,但配置方式如下&#xff1a;android:host"…

android excel布局,Android实现仿excel数据表格效果

在没给大家分享代码之前&#xff0c;先给大家展示下效果图&#xff1a;1.activity/*** 采购需求* Created by Administrator on 2016/10/13.*/public class PurchaseRequireActivity extends BaseActivity implements PurchaseRequireView {Bind(R.id.appTitle)TextView appTit…

android 页面整体滑动,ScrollView 实现页面整体滑动

页眉整体垂直方向滑动&#xff0c;xml文件较为简单&#xff0c;只需要在需要滑动的布局文件中包裹一层ScrollView就可以实现。示例&#xff1a;xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tools"http://schemas.android.com/tools"android:…

首款搭载鸿蒙os的设备,华为发布会配件汇总,首款搭载 鸿蒙OS 的设备来了

2020 年 10 月 30 日&#xff0c;华为召开 Mate40 系列发布会&#xff0c;正式发布 Mate40 系列手机。除了手机&#xff0c;本次发布会还发布了华为 Watch GT2 Pro 手表、华为 Sound 音箱等配件。以下是详细情况&#xff1a;华为智选智能摄像头 Pro该设备是首款搭载 HarmonyOS …

html 纵向选项卡,竖直选项卡式面板的实现_html/css_WEB-ITnose

前面的话&#xff1a;我是html的初学者&#xff0c;懂得一些html的基本知识。最近开始学css&#xff0c;不会JavaScript。了解到adobe dw cs5的插入->spry有选项卡式面板的设计&#xff0c;对这个很感兴趣。但是发现默认的是tab水平排列在上面的。然而多数网站都是tab竖直排…

超鸿蒙混希夷的翻译,对《愚溪诗序》一处译文的思考

《愚溪诗序》文末&#xff0c;柳宗元写道&#xff1a;“以愚辞歌愚溪&#xff0c;则茫然而不违&#xff0c;昏然而同归&#xff0c;超鸿蒙&#xff0c;混希夷&#xff0c;寂寥而莫我知也。”人教版教参对“寂寥”的翻译是“寂寞清静”&#xff0c;对“莫我知”的翻译是“没有谁…

html图片自动切换的幻灯片效果的,js带点自动图片轮播幻灯片特效代码分享

本文实例讲述了javascript带点自动图片轮播幻灯片特效。分享给大家供大家参考。具体如下&#xff1a;这是一款基于javascript实现带点自动图片轮播幻灯片特效代码&#xff0c;实现过程很简单。运行效果图&#xff1a;-------------------查看效果下载源码-------------------小…

省份城市区县三级联动html代码,基于Jquery实现省份、城市、区县三级联动

-//W3C//DTD HTML 4.01 Transitional//EN”“;>$(document).ready(function(){//省份城市数组var fujian_city new Array(‘福州’,’漳州’,’厦门’,’龙岩’,’泉州’,’南平’,’莆田’,’宁德’,’三明’);var guangdong_city new Array(‘广州’,’深圳’,’东莞’,…

html 页面元素id不唯一,规定html元素的唯一的id属性

实例通过 JavaScript 利用 id 属性来改变一段文本&#xff1a;function change_header(){document.getElementById("myHeader").innerHTML"Nice day!";}Hello World!Change text亲自试一试定义和用法id 属性规定 HTML 元素的唯一的 id。id 在 HTML 文档中必…