[关闭]
@orangleliu 2016-03-22T15:44:56.000000Z 字数 1475 阅读 2051

Redis 协议为例谈简单的协议分析

协议 Redis


怎样去研究一个协议的过程,协议的格式,好处,怎么样模拟发包等,下面是一个简单的过程记录。

研究的步骤:
1. 协议相关的资料,RFC,官方文档等。弄清楚协议工作在4层还是7层,是二进制还是文本协议等
2. 抓包,通过分析数据包来真实的看到通信过程,另外一个就是自己实现时候方面调试
3. 看客户端或者服务端的源码,了解实现细节(如果你需要拆轮子和造轮子)
4. 总结下它的优缺点等

1 协议信息

尽量找到原始的资料和精辟的分析

特点小结

二进制安全是什么?

协议描述

RESP协议中,数据类型依赖于第一个字节

不同数据块之间使用 \r\n(CRLF) 来分割

Simple String

简单字符串类型: 编码格式如下,一个 "+" 号,后面跟着字符串(但是不包含 \n或者 \r), 结尾是 \r\n

主要用来传输,比较短的非二进制安全字符串, 例如传递 "OK"。

  1. +OK\r\n

下面的就不介绍了,详细的内容全在 http://redis.io/topics/protocol 文章中,请认真的阅读一遍,其他不管怎么分析最终还是会回到这个协议的文档中来对照。

2 抓包

下面就用 WireShark 来抓几个Redis 客户端服务端通信的包。

例如执行如下命令

  1. 127.0.0.1:6379> set name lzz
  2. OK

一共是4个包,一个是客户端发送指令,一个是服务端返回指令,另外2个是ACK, 主要看客户端发送指令(编号为1的数据包)和服务端返回的指令(编号为4的数据包),见下图。

数据包

编号1的数据包
发送给服务的set命令

数据包1

通过截图可以清晰的看到,TCP包里的data内容,0d0a对应的ASCII字符就是 \r\n, 这样很容易的把客户端的内容还原

  1. *3\r\n$3\r\nset\r\n$4\r\nname\r\n$3\r\nlzz\r\n
  2. 解释
  3. *3\r\n 一个长度为3的数组
  4. $3\r\nset\r\n bulk字符串,长度为3
  5. $4\r\nname\r\n bulk字符串,长度为4
  6. $3\r\nlzz\r\n bulk字符串,长度位3
  7. 最后的结果就是,正好还原了之前客户端的命令
  8. set name lzz

编号4的数据包
服务端返回值

数据包2

这个内容比较简单

  1. +OK\r\n 简单字符串,OK

更复杂的例子也是如此分析,根据data的内容,结合文档中协议的定义,可以比较容易的反推出交互内容。

3 客户端实现

当然这里不仅仅是协议的东西,还涉及很多应用层开发的知识,协议承载的还是应用数据交互,如果有二次开发啦,或者移植到别的语言等需求,还是要好好研究下的。 完成一个简单的协议实现很简单,但是如何让它高效,稳定,经得起考验,还是挺需要功夫的。

4 总结

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注