• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++访问Redis的mset 二进制数据接口封装方案

C++访问Redis的mset 二进制数据接口封装方案

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了redis mset,mset,mset是什么意思,mset破解,mset jap等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

需求

C++中使用hiredis客户端接口访问redis;
需要使用mset一次设置多个二进制数据

以下给出三种封装实现方案;

简单拼接方案

在redis-cli中,mset的语法是这样的:

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

OK

按照这样的语法拼接后,直接使用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;
}

</div>

这种方式可以处理mset多个字符串数据,但对于数据内容为二进制数据的无能为力;

redisCommandArgv接口传递 方案

对于多个参数传递,hiredis提供了以下接口,这个接口中最后一个参数是所有的传入数据的内容长度,
就是说这个接口是二进制安全的:

void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
主要工作就是构造一个动态的二维数组char ** argv,其中涉及到char **到const char **的转换,有一定的风险,
关于这一点前一篇文章已经谈到;

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;
}

</div>

redisCommandArgv接口传递的Vector方案

还是使用redisCommandArgv接口,使用vector来构造这个const char **,这个方法是从参考资料1中学到的:

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 );
}

</div>

这样,就实现二进制数据的传递;

二进制校验

程序执行后,可以用redis-cli来验证:

对于非二进制安全的实现,二进制内容是截断的:

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

而二进制安全的实现接口,二进制数据的0通过转义方式显示:

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

完整可执行的代码详见github:https://github.com/me115/cppset/tree/master/2DimArray

以上所述就是本文的全部内容了,希望大家能够喜欢。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++访问Redis的mset 二进制数据接口封装方案

相关文章

  • 2017-05-28解析C++中虚析构函数的作用
  • 2017-05-28C++如何调用matlab函数
  • 2017-05-28C++实现广度优先搜索实例
  • 2017-05-28浅析多维数组的下标重载
  • 2017-05-28C语言中#define与typedef的互换细节详解
  • 2017-05-28C++十六进制宏的用法详解
  • 2017-05-28Linux下C语言的fork()子进程函数用法及相关问题解析
  • 2017-05-28C实现的非阻塞方式命令行端口扫描器源码
  • 2017-05-28C语言 常量详解及示例代码
  • 2017-05-28C语言实现的程序员老黄历实例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C语言中操作utmp文件的相关函数用法
    • C/C++位操作实例总结
    • 浅析直接插入排序与折半插入排序
    • c#中实现退出程序后自动重新启动程序的方法
    • C++ 中 const和static readonly区别
    • MFC中exe图标修改的方法
    • c语言中数组名a和&a详细介绍
    • C++中虚函数与纯虚函数的用法
    • 如何将C语言代码转换为应用程序(也就是编译)
    • MFC程序对文件的处理方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有