转载

Redis系列(四)—— Redis协议详解,一个简单的客户端

协议

协议是指两个实体(群)之间通信的约定标准,本文主要探讨Redis服务端和客户端交互的协议,其余集群相关的协议留待以后探讨。 协议算是一个必要而伟大的发明。A和B语言不通,但他们可以通过彼此都熟知的方式交流,比如肢体语言,肢体语言在这里就是协议。语言只是交流的一种表现形式,真正的交流与语言无关,就像最早翻译英文的神人,猜想也是用上了肢体语言的吧。除了Redis协议,语言翻译,还有诸如食谱、药方、API都是协议的表现形式,甚至编程语言也可以理解为程序员与机器之间的协议(当然有编译过程)。协议是一种规范,是为了通信双方能在同样的语境下交流,能看得懂,不出错。

Redis协议

Redis协议是基于TCP的,最后都是字节流,一些控制字符加上数据,就是整个协议。(编程语言是关键字加上代码)

首先来看看Redis协议里的对象类型: (1)简单字符串,首字符是‘+’,其后是字符串内容 (2)错误,首字符是'-',其后是错误信息 (3)整数,首字符是':',其后是一个整数 (4)定长字符串,首字符是'$',其后是字符串长度,下面跟字符串,特殊的可以用 "$-1/r/n" 来表示来表示NULL (5)数组,首字符是' ',其后是数据长度,下面是数组内容 Redis客户端和服务端通信都基于这五种基本对象,客户端向服务端只会发送定长字符串数据,服务端会根据命令执行结果返回上面的对象类型。比如一个简单的SET命令 "SET a 12",表示成Redis协议如下:" 3/r/n$3/r/nSET/r/n$1/r/na/r/n$2/r/n12/r/n",其中 "/r/n" Redis用来分隔每个对象,上传命令服务端的回复是 "+OK/r/n",表示命令执行成功。

其它的命令可以用tcpdump抓包并用wireshark分析,tcpdump命令是: sudo tcpdump -nn -i lo0 port 6379 -w wire.cap

然后用wireshark分析包即可,强烈建议实际动手操作一下,对协议的理解大有好处。

Redis客户端——C简陋版

协议搞清楚了,下面简单实验一下,调用一下“SET a 12”这个命令。

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>  int main() {     int cPort = 6379;   int cClient = 0;   int cLen = 0;   struct sockaddr_in cli;   char cbuf[4096] = {0};    memset(cbuf, 0, sizeof(cbuf));    cli.sin_family = AF_INET;   cli.sin_port = htons(cPort);   cli.sin_addr.s_addr = inet_addr("127.0.0.1");    cClient = socket(AF_INET, SOCK_STREAM, 0);   if (cClient < 0) {     printf("socket() failure!/n");     return -1;   }    if (connect(cClient, (struct sockaddr*)&cli, sizeof(cli)) < 0) {     printf("connect() failure!/n");     return -1;   }    //send command   char command[] = "*3/r/n$3/r/nSET/r/n$1/r/na/r/n$2/r/n12/r/n";   if (send(cClient, command, sizeof(command), 0) == -1) {     printf("send failure/n");     return -1;   }    cLen = recv(cClient, cbuf, sizeof(cbuf), 0);   if ((cLen < 0) || (cLen == 0)) {       printf("recv() failure!/n");       return -1;   }   printf("recv() Data From Server: [%s]/n", cbuf);    close(cClient);    return 0; } 

最后说一句

目前正在着手Redis系列文章,设计Redis基本原理、使用、运维、底层架构,大家有感兴趣的话题,可以联系我

  • 微博: http://weibo.com/u/3315127322
  • 知乎: https://www.zhihu.com/people/li-bo-87-68
原文  http://sanpi.li/redis-xi-lie-si-redisxie-yi-xiang-jie-yi-ge-jian-dan-de-ke-hu-duan/
正文到此结束
Loading...