日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發布時間:2025/3/12 linux 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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

總結

以上是生活随笔為你收集整理的linux c 封装redis,封装hiredis——C++与redis对接(一)(string的SET与GET操作)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。