RESP3
先整体列举一下:
NULL
代表 resp2
中的 *-1\r\n
或者 $-1\r\n
_\r\n
复制代码
Double
,1.23\r\n
复制代码
Boolean
#t\r\n
#f\r\n
复制代码
二进制安全的error
!21\r\nSYNTAX invalid syntax\r\n
复制代码
Verbatim string
=15<CR><LF>
txt:Some string<CR><LF>
复制代码
Verbatim string
=15<CR><LF>
txt:Some string<CR><LF>
复制代码
Map
%2<CR><LF>
+first<CR><LF>
:1<CR><LF>
+second<CR><LF>
:2<CR><LF>
复制代码
Set
~5<CR><LF>
+orange<CR><LF>
+apple<CR><LF>
#t<CR><LF>
:100<CR><LF>
:999<CR><LF>
复制代码
Hello
建立连接时,返回服务端名称,版本等等
# 发送这个,可以切换成 RESP3
HELLO 3
复制代码
接收
server
端接收到命令首先存储在客户端对象的querybuf
输入缓冲区- 然后开始解析命令,各个参数;并存储在客户端对象的
argv(参数对象),argc(参数数目)
来说说第2个,具体的解析过程:
- 解析请求参数数目
- 循环解析每个请求参数
参数数目
走的是多行解析, processMultibulkBuffer
,那么第一个字符 *
得识别出来:
// 读入命令的参数个数
// 比如 *3\r\n$3\r\nSET\r\n... 将令 c->multibulklen = 3
if (c->multibulklen == 0) {
redisAssertWithInfo(c,NULL,c->argc == 0);
// 检查缓冲区的内容第一个 "\r\n"
newline = strchr(c->querybuf,'\r');
...
// 协议的第一个字符必须是 '*'
redisAssertWithInfo(c,NULL,c->querybuf[0] == '*');
// 将参数个数,也即是 * 之后, \r\n 之前的数字取出并保存到 ll 中
// 比如对于 *3\r\n ,那么 ll 将等于 3
// ----> 【C语言的多返回值操作】很秀:&ll
ok = string2ll(c->querybuf+1,newline-(c->querybuf+1),&ll);
// 参数的数量超出限制
if (!ok || ll > 1024*1024) {
addReplyError(c,"Protocol error: invalid multibulk length");
setProtocolError(c,pos);
return REDIS_ERR;
}
// 参数数量之后的位置
// 比如对于 *3\r\n$3\r\nSET\r\n... 来说,
// pos 指向 *3\r\n$3\r\nSET\r\n...
// ^
// |
// pos
// 记录已解析位置偏移量
pos = (newline-c->querybuf)+2;
// 如果 ll <= 0 ,那么这个命令是一个空白命令
...
// 设置参数数量
c->multibulklen = ll;
...
}
复制代码
循环解析参数
上述结束时出来的协议:$3\r\nSET\r\n
// 读入参数长度
if (c->bulklen == -1) {
// 确保 "\r\n" 存在
newline = strchr(c->querybuf+pos,'\r');
...
// 确保协议符合参数格式,检查其中的 $...
// 比如 $3\r\nSET\r\n
if (c->querybuf[pos] != '$') {
return REDIS_ERR;
}
// 读取长度
// 比如 $3\r\nSET\r\n 将会让 ll 的值设置 3
ok = string2ll(c->querybuf+pos+1,newline-(c->querybuf+pos+1),&ll);
...
// 定位到参数的开头
// 比如
// $3\r\nSET\r\n...
// ^
// |
// pos
pos += newline-(c->querybuf+pos)+2;
...
// 参数的长度
c->bulklen = ll;
}
复制代码
解析出来参数字符串长度之后:
- 创建字符串对象
- 更新
multibulklen
,multibulklen--
当 multibulklen
更新到0,说明参数解析完毕。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END