PHP8.1.21版本已发布
vue8.1.21版本已发布
jquery8.1.21版本已发布

Redis客户端与服务端通信协议

原创
2016-06-07 15:23:06 854浏览

背景 在跟踪REDIS服务端处理命令流程的时候,发现在服务端processInputBuffer里收到的字符串并非是在客户端输入的,而是进行了某种编码。比如,客户端输入get a,实际服务端打印出来的是 buf= *2$3get$1a 最开始认为是在服务端某段代码对客户端送过来的字符

背景

在跟踪REDIS服务端处理命令流程的时候,发现在服务端processInputBuffer里收到的字符串并非是在客户端输入的,而是进行了某种编码。比如,客户端输入get a,实际服务端打印出来的是
buf= *2
$3
get
$1
a
最开始认为是在服务端某段代码对客户端送过来的字符串进行处理,可能是出于某些考虑,后来发现从SOCKET读取过来就已经转换过了,所以就应该是客户端和服务端的通信协议,我对这个就开始产生了很浓厚的兴趣,*和$符号必定是有特殊意义的。

客户端处理流程

在main函数启动后,与服务端进行连接调用repl()函数,在该函数初始化和调用命令行的历史记录(允许你上下翻动历史)。最后进入cliSendCommand函数处理命令,对于需要发送到服务端的命令调用redisAppendCommandArgv的流程。
为了分析里面的通信协议,对redisAppendCommandArgv函数的黑盒测试,得出以下规律。
客户输入内容 处理结果
a *1
$1
a
ab *1
$2
ab
a b *2
$1
a
$1
b
get a b *3
$3
get
$1
a
$1
b
get a ab *3
$3
get
$1
a
$2
ab

可以得出规律,是将argc argv在具体化,第一个参数,也就是*开始相当于argc, 表示后续有几个对象,$后面的数字表示紧跟后面的字符串有几个字节。如get a ab,一共3个,分别是get ,a,b。 $3表示后面的get是3个字节。

官方文档

之前都是自己根据代码的跟踪猜的,更详细的更专业的回答在这里。
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。