欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++訪問Redis的mset 二進(jìn)制數(shù)據(jù)接口封裝方案

 更新時(shí)間:2015年07月01日 10:10:22   投稿:hebedich  
這篇文章主要介紹了C++訪問Redis的mset 二進(jìn)制數(shù)據(jù)接口封裝方案的相關(guān)資料,需要的朋友可以參考下

需求

C++中使用hiredis客戶端接口訪問redis;
需要使用mset一次設(shè)置多個(gè)二進(jìn)制數(shù)據(jù)

以下給出三種封裝實(shí)現(xiàn)方案;

簡(jiǎn)單拼接方案

在redis-cli中,mset的語(yǔ)法是這樣的:

復(fù)制代碼 代碼如下:

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

OK

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

void msetNotBinary(redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal )
{
  if(vtKey.size() != vtVal.size())
  {
    throw runtime_error( "Redis error" );
  }

  string strCmd = "MSET";
  for(int i = 0; i < vtKey.size(); i++)
  {
    strCmd += " "+vtKey[i]+" "+vtVal[i];
  }
  cout << "strCmd:" << strCmd << endl;

  void * r = redisCommand(c, strCmd.c_str() );
  if ( !r )
    throw runtime_error( "Redis error" );
  freeReplyObject( r );
}

void do_test( redisContext *c )
{  
  vector<string> vtKey;
  vector<string> vtVal;

  vtKey.push_back("A");
  vtVal.push_back("AAAA");
  vtKey.push_back("B");
  vtVal.push_back("BBBB");
  vtKey.push_back("C");
  vtVal.push_back("CCCC");
  //add a binary data
  vtKey.push_back("D");
  vtVal.push_back("");
  char a[] = "ABCDE";
  a[2] = 0;
  vtVal[3].assign(a,5);

  try
  {
    msetNotBinary(c, vtKey, vtVal );
    //mset1( c, vtKey, vtVal );
    //mset2( c, vtKey, vtVal );
  }
  catch ( runtime_error & )
  {
    cout << "Error" << endl;
  }
}

int main(int argc, char *argv[])
{
  redisContext *c;

  c = redisConnect("127.0.0.1",6379);
  if (c->err)
   {
    cout << "Connection error: " << c->errstr << endl;
    return -1;
  }

  do_test(c);

  redisFree(c);

  return 0;
}

這種方式可以處理mset多個(gè)字符串?dāng)?shù)據(jù),但對(duì)于數(shù)據(jù)內(nèi)容為二進(jìn)制數(shù)據(jù)的無(wú)能為力;

redisCommandArgv接口傳遞 方案

對(duì)于多個(gè)參數(shù)傳遞,hiredis提供了以下接口,這個(gè)接口中最后一個(gè)參數(shù)是所有的傳入數(shù)據(jù)的內(nèi)容長(zhǎng)度,
就是說(shuō)這個(gè)接口是二進(jìn)制安全的:

void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
主要工作就是構(gòu)造一個(gè)動(dòng)態(tài)的二維數(shù)組char ** argv,其中涉及到char **到const char **的轉(zhuǎn)換,有一定的風(fēng)險(xiǎn),
關(guān)于這一點(diǎn)前一篇文章已經(jīng)談到;

void mset1( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal )
{
  if(vtKey.size() != vtVal.size())
  {
    throw runtime_error( "Redis error" );
  }

  char ** argv = new char*[vtKey.size() + vtVal.size() + 1 ];
  size_t * argvlen = new size_t[vtKey.size() + vtVal.size() + 1 ];

  int j = 0;
  argv[j] = new char[5];
  memcpy(argv[j],"MSET",4);
  argvlen[j] = 4;
  ++j;


  for(int i = 0 ; i < vtKey.size();i++)
  {  
    argvlen[j] = vtKey[i].length();
    argv[j] = new char[argvlen[j]];
     memset((void*)argv[j],0,argvlen[j] );
    memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length());
    j++;

    argvlen[j] = vtVal[i].length();
    argv[j] = new char[argvlen[j]];
    memset((void*)argv[j],0,argvlen[j]);
    memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length());
    j++;
  }

  //if not use const_cast<const char**> ,compile error
  //for why assign from char** to const char** error, see my blog ...
   void *r = redisCommandArgv(c, vtKey.size() + vtVal.size() + 1, const_cast<const char**>(argv), argvlen );
  if ( !r )
    throw runtime_error( "Redis error" );
  freeReplyObject( r );

  for(int i = 0;i < vtKey.size();i++)
  {
    delete [] argv[i];
    argv[i] = NULL;
  }

  delete []argv;
  delete []argvlen;
  argv = NULL;
}

redisCommandArgv接口傳遞的Vector方案

還是使用redisCommandArgv接口,使用vector來(lái)構(gòu)造這個(gè)const char **,這個(gè)方法是從參考資料1中學(xué)到的:

void mset2( redisContext *c, const vector<string> &vtKey, const vector<string> & vtVal)
{
  if(vtKey.size() != vtVal.size())
  {
    throw runtime_error( "Redis error" );
  }

  vector<const char *> argv( vtKey.size() + vtVal.size() + 1 );
  vector<size_t> argvlen( vtKey.size() + vtVal.size() + 1 );
  int j = 0;

  static char msetcmd[] = "MSET";
  argv[j] = msetcmd;
  argvlen[j] = sizeof(msetcmd)-1;
  ++j;

  for(int i = 0;i< vtKey.size();++i)
  {
    argvlen[j] = vtKey[i].length();
    argv[j] = new char[argvlen[j]];
     memset((void*)argv[j],0,argvlen[j] );
    memcpy((void*)argv[j],vtKey[i].data(),vtKey[i].length());
    j++;

    argvlen[j] = vtVal[i].length();
    argv[j] = new char[argvlen[j]];
    memset((void*)argv[j],0,argvlen[j]);
    memcpy((void*)argv[j],vtVal[i].data(),vtVal[i].length());
    j++;
  }

  void *r = redisCommandArgv(c, argv.size(), &(argv[0]), &(argvlen[0]) );
  if ( !r )
    throw runtime_error( "Redis error" );
  freeReplyObject( r );
}

這樣,就實(shí)現(xiàn)二進(jìn)制數(shù)據(jù)的傳遞;

二進(jìn)制校驗(yàn)

程序執(zhí)行后,可以用redis-cli來(lái)驗(yàn)證:

對(duì)于非二進(jìn)制安全的實(shí)現(xiàn),二進(jìn)制內(nèi)容是截?cái)嗟模?/p>

復(fù)制代碼 代碼如下:

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

而二進(jìn)制安全的實(shí)現(xiàn)接口,二進(jìn)制數(shù)據(jù)的0通過(guò)轉(zhuǎn)義方式顯示:

復(fù)制代碼 代碼如下:

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

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

以上所述就是本文的全部?jī)?nèi)容了,希望大家能夠喜歡。

相關(guān)文章

  • 深入理解C++的對(duì)象模型

    深入理解C++的對(duì)象模型

    本文在介紹C++使用的對(duì)象模型之前,先介紹了2種對(duì)象模型:簡(jiǎn)單對(duì)象模型(a simple object model)和表格驅(qū)動(dòng)對(duì)象模型(a table-driven object model),這樣介紹對(duì)后面的內(nèi)容更有幫助,有需要的小伙伴們可以參考學(xué)習(xí)。
    2016-08-08
  • C語(yǔ)言解決字符串中插入和刪除某段字符串問題

    C語(yǔ)言解決字符串中插入和刪除某段字符串問題

    這篇文章主要介紹了C語(yǔ)言解決字符串中插入和刪除某段字符串問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Qt中鼠標(biāo)點(diǎn)擊的幾種狀態(tài)

    Qt中鼠標(biāo)點(diǎn)擊的幾種狀態(tài)

    在Qt中,鼠標(biāo)點(diǎn)擊按鈕通常會(huì)觸發(fā)一系列的事件,包括pressed、released、clicked等,本文主要介紹了Qt中鼠標(biāo)點(diǎn)擊的幾種狀態(tài),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • cocos2dx-3.10 C++實(shí)現(xiàn)滾動(dòng)數(shù)字

    cocos2dx-3.10 C++實(shí)現(xiàn)滾動(dòng)數(shù)字

    這篇文章主要為大家詳細(xì)介紹了cocos2dx-3.10 C++實(shí)現(xiàn)滾動(dòng)數(shù)字效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C語(yǔ)言將數(shù)組中元素的數(shù)排序輸出的相關(guān)問題解決

    C語(yǔ)言將數(shù)組中元素的數(shù)排序輸出的相關(guān)問題解決

    這篇文章主要介紹了C語(yǔ)言將數(shù)組中元素的數(shù)排序輸出的相關(guān)問題解決,文中的題目是將元素連接起來(lái)排成一個(gè)數(shù)并要求出這類結(jié)果中數(shù)最小的一個(gè),需要的朋友可以參考下
    2016-03-03
  • C/C++指針和取地址的方法

    C/C++指針和取地址的方法

    C/C++指針和取地址的方法,需要的朋友可以參考一下
    2013-04-04
  • C語(yǔ)言實(shí)現(xiàn)外賣管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)外賣管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)外賣管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • C++標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)WAV文件讀寫的操作

    C++標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)WAV文件讀寫的操作

    本文將使用標(biāo)準(zhǔn)C++庫(kù)實(shí)現(xiàn)對(duì)數(shù)據(jù)為PCM格式的WAV文件的讀寫操作,只使用標(biāo)準(zhǔn)C++庫(kù)函數(shù),不依賴于其他的庫(kù),對(duì)C++標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)WAV文件讀寫相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-01-01
  • c語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)之字符串

    c語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)之字符串

    這篇文章主要介紹了c語(yǔ)言 數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)之字符串的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C語(yǔ)言編寫基于TCP和UDP協(xié)議的Socket通信程序示例

    C語(yǔ)言編寫基于TCP和UDP協(xié)議的Socket通信程序示例

    這篇文章主要介紹了C語(yǔ)言編寫基于TCP和UDP協(xié)議的Socket通信程序示例,其中TCP的客戶端與服務(wù)器端采用多線程實(shí)現(xiàn),需要的朋友可以參考下
    2016-03-03

最新評(píng)論