亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++訪問Redis的mset 二進制數據接口封裝方案

2020-05-23 14:19:23
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了C++訪問Redis的mset 二進制數據接口封裝方案的相關資料,需要的朋友可以參考下
 

需求

C++中使用hiredis客戶端接口訪問redis; 
需要使用mset一次設置多個二進制數據

以下給出三種封裝實現方案;

簡單拼接方案

在redis-cli中,mset的語法是這樣的:

 

復制代碼代碼如下:

/opt/colin$./redis-cli mset a 11 b 22 c 333

 

OK

按照這樣的語法拼接后,直接使用hiredis字符串接口redisCommand傳遞:
 

  1. void msetNotBinary(redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal ) 
  2.   if(vtKey.size() != vtVal.size()) 
  3.   { 
  4.     throw runtime_error( "Redis error" ); 
  5.   } 
  6.  
  7.   string strCmd = "MSET"
  8.   for(int i = 0; i < vtKey.size(); i++) 
  9.   { 
  10.     strCmd += " "+vtKey[i]+" "+vtVal[i]; 
  11.   } 
  12.   cout << "strCmd:" << strCmd << endl; 
  13.  
  14.   void * r = redisCommand(c, strCmd.c_str() ); 
  15.   if ( !r ) 
  16.     throw runtime_error( "Redis error" ); 
  17.   freeReplyObject( r ); 
  18.  
  19. void do_test( redisContext *c ) 
  20. {   
  21.   vector<string> vtKey; 
  22.   vector<string> vtVal; 
  23.  
  24.   vtKey.push_back("A"); 
  25.   vtVal.push_back("AAAA"); 
  26.   vtKey.push_back("B"); 
  27.   vtVal.push_back("BBBB"); 
  28.   vtKey.push_back("C"); 
  29.   vtVal.push_back("CCCC"); 
  30.   //add a binary data 
  31.   vtKey.push_back("D"); 
  32.   vtVal.push_back(""); 
  33.   char a[] = "ABCDE"
  34.   a[2] = 0; 
  35.   vtVal[3].assign(a,5); 
  36.  
  37.   try 
  38.   { 
  39.     msetNotBinary(c, vtKey, vtVal ); 
  40.     //mset1( c, vtKey, vtVal ); 
  41.     //mset2( c, vtKey, vtVal ); 
  42.   } 
  43.   catch ( runtime_error & ) 
  44.   { 
  45.     cout << "Error" << endl; 
  46.   } 
  47.  
  48. int main(int argc, char *argv[]) 
  49.   redisContext *c; 
  50.  
  51.   c = redisConnect("127.0.0.1",6379); 
  52.   if (c->err) 
  53.    { 
  54.     cout << "Connection error: " << c->errstr << endl; 
  55.     return -1; 
  56.   } 
  57.  
  58.   do_test(c); 
  59.  
  60.   redisFree(c); 
  61.  
  62.   return 0; 
?

這種方式可以處理mset多個字符串數據,但對于數據內容為二進制數據的無能為力;

redisCommandArgv接口傳遞 方案

對于多個參數傳遞,hiredis提供了以下接口,這個接口中最后一個參數是所有的傳入數據的內容長度, 
就是說這個接口是二進制安全的:

void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
主要工作就是構造一個動態的二維數組char ** argv,其中涉及到char **到const char **的轉換,有一定的風險, 
關于這一點前一篇文章已經談到;
 

  1. void mset1( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal ) 
  2.   if(vtKey.size() != vtVal.size()) 
  3.   { 
  4.     throw runtime_error( "Redis error" ); 
  5.   } 
  6.  
  7.   char ** argv = new char*[vtKey.size() + vtVal.size() + 1 ]; 
  8.   size_t * argvlen = new size_t[vtKey.size() + vtVal.size() + 1 ]; 
  9.  
  10.   int j = 0; 
  11.   argv[j] = new char[5]; 
  12.   memcpy(argv[j],"MSET",4); 
  13.   argvlen[j] = 4; 
  14.   ++j; 
  15.  
  16.  
  17.   for(int i = 0 ; i < vtKey.size();i++) 
  18.   {   
  19.     argvlen[j] = vtKey[i].length(); 
  20.     argv[j] = new char[argvlen[j]]; 
  21.      memset((void*)argv[j],0,argvlen[j] ); 
  22.     memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length()); 
  23.     j++; 
  24.  
  25.     argvlen[j] = vtVal[i].length(); 
  26.     argv[j] = new char[argvlen[j]]; 
  27.     memset((void*)argv[j],0,argvlen[j]); 
  28.     memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length()); 
  29.     j++; 
  30.   } 
  31.  
  32.   //if not use const_cast<const char**> ,compile error 
  33.   //for why assign from char** to const char** error, see my blog ... 
  34.    void *r = redisCommandArgv(c, vtKey.size() + vtVal.size() + 1, const_cast<const char**>(argv), argvlen ); 
  35.   if ( !r ) 
  36.     throw runtime_error( "Redis error" ); 
  37.   freeReplyObject( r ); 
  38.  
  39.   for(int i = 0;i < vtKey.size();i++) 
  40.   { 
  41.     delete [] argv[i]; 
  42.     argv[i] = NULL; 
  43.   } 
  44.  
  45.   delete []argv; 
  46.   delete []argvlen; 
  47.   argv = NULL; 
?

redisCommandArgv接口傳遞的Vector方案

還是使用redisCommandArgv接口,使用vector來構造這個const char **,這個方法是從參考資料1中學到的:
 

  1. void mset2( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal) 
  2.   if(vtKey.size() != vtVal.size()) 
  3.   { 
  4.     throw runtime_error( "Redis error" ); 
  5.   } 
  6.  
  7.   vector<const char *> argv( vtKey.size() + vtVal.size() + 1 ); 
  8.   vector<size_t> argvlen( vtKey.size() + vtVal.size() + 1 ); 
  9.   int j = 0; 
  10.  
  11.   static char msetcmd[] = "MSET"
  12.   argv[j] = msetcmd; 
  13.   argvlen[j] = sizeof(msetcmd)-1; 
  14.   ++j; 
  15.  
  16.   for(int i = 0;i< vtKey.size();++i) 
  17.   { 
  18.     argvlen[j] = vtKey[i].length(); 
  19.     argv[j] = new char[argvlen[j]]; 
  20.      memset((void*)argv[j],0,argvlen[j] ); 
  21.     memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length()); 
  22.     j++; 
  23.  
  24.     argvlen[j] = vtVal[i].length(); 
  25.     argv[j] = new char[argvlen[j]]; 
  26.     memset((void*)argv[j],0,argvlen[j]); 
  27.     memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length()); 
  28.     j++; 
  29.   } 
  30.  
  31.   void *r = redisCommandArgv(c, argv.size(), &(argv[0]), &(argvlen[0]) ); 
  32.   if ( !r ) 
  33.     throw runtime_error( "Redis error" ); 
  34.   freeReplyObject( r ); 
?

這樣,就實現二進制數據的傳遞;

二進制校驗

程序執行后,可以用redis-cli來驗證:

對于非二進制安全的實現,二進制內容是截斷的:

 

復制代碼代碼如下:

/opt/app/colin$./redis-cli get D
"AB"

 

而二進制安全的實現接口,二進制數據的0通過轉義方式顯示:

 

復制代碼代碼如下:

/opt/app/colin$./redis-cli get D
"AB/x00DE"

 

完整可執行的代碼詳見github:https://github.com/me115/cppset/tree/master/2DimArray

以上所述就是本文的全部內容了,希望大家能夠喜歡。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91精品在线国产| 成人激情春色网| 在线看欧美日韩| 色综合影院在线| 国产亚洲精品久久久优势| 久久久女人电视剧免费播放下载| 欧美国产一区二区三区| 欧美性猛交xxxx免费看| 国产精品aaaa| 亚洲美女www午夜| 国产亚洲欧美日韩美女| 在线精品国产欧美| 精品国产欧美一区二区三区成人| 欧美激情欧美狂野欧美精品| 91欧美激情另类亚洲| 精品欧美激情精品一区| 欧美性xxxx18| 亚洲第一黄色网| 北条麻妃久久精品| 久久亚洲精品视频| 日韩在线中文视频| 久久九九国产精品怡红院| 亚洲国产一区二区三区四区| 亚洲欧美日韩网| 亚洲午夜性刺激影院| 在线丨暗呦小u女国产精品| 国产成人高潮免费观看精品| 91av在线精品| 国产91精品久久久久| 久久久久久91香蕉国产| 国产精自产拍久久久久久| 夜夜嗨av一区二区三区四区| 91精品国产综合久久香蕉最新版| 亚洲人在线视频| 97香蕉久久夜色精品国产| 久久韩国免费视频| 久久久国产精品亚洲一区| 尤物99国产成人精品视频| 日韩久久精品电影| 色偷偷av一区二区三区乱| 中国china体内裑精亚洲片| 久久久精品电影| 欧美区二区三区| 亚洲人成人99网站| 2019亚洲日韩新视频| 亚洲国产高清自拍| 欧洲日韩成人av| 亚洲女性裸体视频| 国产精品嫩草影院久久久| 尤物99国产成人精品视频| 国产亚洲成精品久久| 国产精品视频网址| 亚洲视频专区在线| 欧美激情性做爰免费视频| 国产成人亚洲综合91精品| 亚洲第一网中文字幕| 91精品国产沙发| 日韩69视频在线观看| 2018中文字幕一区二区三区| 91精品国产自产在线| 色av吧综合网| 亚洲一区二区三区成人在线视频精品| 国产精品户外野外| 色综合久久久久久中文网| 久久精品国产99国产精品澳门| 久久精品最新地址| 欧美日韩一区二区免费在线观看| 久久久成人精品| 日韩在线观看电影| 国产视频久久久久久久| 国产亚洲精品91在线| 欧美一级bbbbb性bbbb喷潮片| 精品香蕉一区二区三区| 国产日韩精品在线播放| 欧美激情精品久久久久久黑人| 亚洲成人国产精品| 乱亲女秽乱长久久久| 亚洲无亚洲人成网站77777| 久久精品国产清自在天天线| 亚洲社区在线观看| 久久国产精品99国产精| 国产精品无av码在线观看| 最近2019中文字幕第三页视频| 亚洲高清福利视频| 色哟哟网站入口亚洲精品| 国内揄拍国内精品少妇国语| 91精品国产色综合久久不卡98口| 亚洲aa中文字幕| 久久九九有精品国产23| 日韩av在线免播放器| 丝袜美腿精品国产二区| 亚洲精品永久免费精品| 日韩精品在线电影| 亚洲第一免费网站| 日韩精品在线电影| 亚洲永久免费观看| 国产精品久久一区| 久久久久久国产精品久久| 国产成人avxxxxx在线看| 51ⅴ精品国产91久久久久久| 欧美乱大交xxxxx另类电影| 国产精品久久久亚洲| 国产精品久久激情| 97涩涩爰在线观看亚洲| 欧美日本中文字幕| 欧美精品999| 久久国产精品偷| 91久久久国产精品| 国内外成人免费激情在线视频| 日韩麻豆第一页| 久久免费精品日本久久中文字幕| 亚洲视频axxx| 92福利视频午夜1000合集在线观看| 57pao成人永久免费视频| 国产丝袜一区视频在线观看| 国产日韩欧美日韩大片| 亚洲国产精品电影在线观看| 日韩亚洲第一页| 欧美激情一区二区三区在线视频观看| 日韩欧美aaa| 国产成+人+综合+亚洲欧洲| 九九视频直播综合网| 久久久欧美一区二区| 福利一区视频在线观看| 日韩中文字幕免费看| 久久综合免费视频影院| 久久久精品一区二区| 91大神在线播放精品| 久久成人亚洲精品| 精品国产1区2区| 久久久国产精品x99av| 日韩美女毛茸茸| 一区二区三区四区精品| 亚洲国产另类 国产精品国产免费| 亚洲美女黄色片| 久久69精品久久久久久久电影好| 95av在线视频| 亚洲色图50p| 亚洲男人第一av网站| 亚洲精品中文字幕女同| 亚洲网址你懂得| 一区三区二区视频| 久久精品亚洲一区| 国产成人精品久久二区二区91| 亚洲美女性视频| 亚洲mm色国产网站| 国产成人免费91av在线| 精品高清美女精品国产区| 欧美日韩国产在线播放| 国产综合色香蕉精品| 3344国产精品免费看| 日韩久久精品电影| 国产精品久久久久久久久久久久久| 精品免费在线观看| 麻豆国产精品va在线观看不卡| 成人激情视频在线观看| 日韩成人av在线播放| 亚洲人成电影网站色www| 欧美色欧美亚洲高清在线视频| 全色精品综合影院| 2023亚洲男人天堂| 久久精品国产v日韩v亚洲| 日韩中文字幕网址| 国产一区二区三区中文|