Redis 协议为例谈简单的协议分析
怎样去研究一个协议的过程,协议的格式,好处,怎么样模拟发包等,下面是一个简单的过程记录。
研究的步骤:
- 协议相关的资料,RFC,官方文档等。弄清楚协议工作在4层还是7层,是二进制还是文本协议等
- 抓包,通过分析数据包来真实的看到通信过程,另外一个就是自己实现时候方面调试
- 看客户端或者服务端的源码,了解实现细节(如果你需要拆轮子和造轮子)
- 总结下它的优缺点等
1 协议信息
尽量找到原始的资料和精辟的分析
- Redis Protocol specification
- Request/Response protocols and RTT
- A Beginner’s Guide to the Redis Protocol
特点小结
- Redis 客户端和服务端交互的协议叫做 RESP(REdis Serialization Protocol),Redis集群中节点交互用的不是这协议
- RESP是二进制安全的, 支持多种数据格式
- RESP工作在TCP层,基于文本的协议,服务端默认端口是6379
- 基本是基于请求-响应的模式, piplining和sub/pub两个除外
协议描述
RESP协议中,数据类型依赖于第一个字节
- Simple String 第一个字节是
"+" - Error 第一个字节是
"-" - Integers 第一个字节是
":" - Bulk String 第一个字节是
"$" - Arrays 第一个字节是
"*"
不同数据块之间使用 \r\n(CRLF) 来分割
Simple String
简单字符串类型: 编码格式如下,一个 “+” 号,后面跟着字符串(但是不包含 \n或者 \r), 结尾是 \r\n。
主要用来传输,比较短的非二进制安全字符串, 例如传递 “OK”。
+OK\r\n
下面的就不介绍了,详细的内容全在 http://redis.io/topics/protocol 文章中,请认真的阅读一遍,其他不管怎么分析最终还是会回到这个协议的文档中来对照。
2 抓包
下面就用 WireShark 来抓几个Redis 客户端服务端通信的包。
例如执行如下命令
127.0.0.1:6379> set name lzz
OK
一共是4个包,一个是客户端发送指令,一个是服务端返回指令,另外2个是ACK, 主要看客户端发送指令(编号为1的数据包)和服务端返回的指令(编号为4的数据包),见下图。

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

通过截图可以清晰的看到,TCP包里的data内容,0d0a对应的ASCII字符就是 \r\n, 这样很容易的把客户端的内容还原
*3\r\n$3\r\nset\r\n$4\r\nname\r\n$3\r\nlzz\r\n
解释
*3\r\n 一个长度为3的数组
$3\r\nset\r\n bulk字符串,长度为3
$4\r\nname\r\n bulk字符串,长度为4
$3\r\nlzz\r\n bulk字符串,长度位3
最后的结果就是,正好还原了之前客户端的命令
set name lzz
编号4的数据包
服务端返回值

这个内容比较简单
+OK\r\n 简单字符串,OK
更复杂的例子也是如此分析,根据data的内容,结合文档中协议的定义,可以比较容易的反推出交互内容。
3 客户端实现
当然这里不仅仅是协议的东西,还涉及很多应用层开发的知识,协议承载的还是应用数据交互,如果有二次开发啦,或者移植到别的语言等需求,还是要好好研究下的。 完成一个简单的协议实现很简单,但是如何让它高效,稳定,经得起考验,还是挺需要功夫的。
4 总结
- 数据格式非常简单
- 基于文本的协议,可读性好
- 协议中控制字段非常少,很简洁,解析高效
- 协议本身是明文,公网使用注意加密传输
Redis 协议为例谈简单的协议分析的更多相关文章
- 【http协议】浅谈
[http协议]浅谈 一. 概述 http,超文本传输协议(HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议. 请求与响应: 客户端发送请求,服务器端响应数 ...
- 转:基于HTTP协议的轻量级开源简单队列服务:HTTPSQS
[文章作者:张宴 本文版本:v1.7.1 最后修改:2011.11.04 转载请注明原文链接:http://blog.zyan.cc/httpsqs/] HTTPSQS(HTTP Simple Que ...
- NetAnalyzer笔记 之 二. 简单的协议分析
[创建时间:2015-08-27 22:15:17] NetAnalyzer下载地址 上篇我们回顾完了NetAnalyzer一些可有可无的历史,在本篇,我决定先不对NetAnalyzer做介绍,而是先 ...
- Paxos协议超级详细解释+简单实例
转载自: https://blog.csdn.net/cnh294141800/article/details/53768464 Paxos协议超级详细解释+简单实例 Basic-Paxos算法 ...
- 旧文备份:简单CANOpen 协议说明
(十年前的旧文,不舍等扔) 创建日期:2005-11-17 修改日期:2005-11-17 文件名称:简单CANOpen 协议说明.doc 作者:winshton 版本:V1.0 (注:本文以24in ...
- 基于HTTP协议的轻量级开源简单队列服务:HTTPSQS[转]
HTTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key ...
- TFTP简单文件传送协议
T F T P ( Trivial File Transfer Protocol)即简单文件传送协议,最初打算用于引导无盘系统(通常是工作站或X终端).和将在介绍的使用T C P的文件传送协议(F T ...
- SNMP简单网络管理协议
声明:以下内容是学习谌玺老师视频整理出来(http://edu.51cto.com/course/course_id-861.html) SNMP(Simple Network Management ...
- SNMP简单网络管理协议(转载)
SNMP SNMP 网络管理的历史 美国国防部设计了世界上头几个包交换网之一的ARPANET,在70年代,TCP/IP协议族正式被定为军方通信标准,随着此协议的广泛使用,网络管理成了一件大事.在80年 ...
随机推荐
- Struts 2 之 OGNL
OGNL概述 Object-Graph Navigation Language,对象图导航语言 1.能够访问对象的方法,如list.size() 2.能够访问静态属性与静态方法,需要在类名前加上@,如 ...
- RocketMQ,JStorm与Tair使用笔记
关于RocketMQ 启动mq nohup sh mqnamesrv -n 10.150.0.94:9876 & nohup sh mqbroker -n 10.150.0.94:9876 ...
- 安卓自定义View实现图片上传进度显示(仿QQ)
首先看下我们想要实现的效果如下图(qq聊天中发送图片时的效果): 再看下图我们实现的效果: 实现原理很简单,首先我们上传图片时需要一个进度值progress,这个不管是自己写的上传的方法还是使用第三方 ...
- 深入浅出Tabhost+简单入门Demo
小伙伴们在手机上逛淘宝的时候,会发现在淘宝的下面有个按钮,分别是首页.微淘.社区.购物车和我的淘宝,点击不同的按钮会跳转到不同的页面,目前小编所接手的这个项目,也需要用到类似这样的功能,小编就发挥网络 ...
- tomcat中Servlet的工作机制
在研究Servlet在tomcat中的工作机制前必须先看看Servlet规范的一些重要的相关规定,规范提供了一个Servlet接口,接口中包含的重要方法是init.service.destroy等方法 ...
- Python爬虫! 单爬,批量爬,这都不是事!
昨天做了一个煎蛋网妹子图的爬虫,个人感觉效果不错.但是每次都得重复的敲辣么多的代码(相比于Java或者其他语言的爬虫实现,Python的代码量可谓是相当的少了),就封装了一下!可以实现对批量网址以及单 ...
- Android的ScrollView和HorizontalScrollView-android学习之旅(四十一)
HorizontalScrollView和ScrollView简介 ScrollView和HorizontalScrollView都继承于FrameLayout组件,两个都是容器,前者为里面的组件添加 ...
- IOS中 浅谈iOS中MVVM的架构设计与团队协作
今天写这篇文章是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇文章的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- Unity UGUI基础之Text
Text作为UGUI最基础的控件以及最常用的控件,它在项目中的应用绝对可以算是最多的,任何一个UI界面可以说都离不开它,它的基本属性如下: 一.rect transform组件: rect trans ...
- C# 运行时序列化
一. 序列化与反序列的作用 为什么要有序列化呢,考虑下面这种情况,在WINFORM或者更为方便的WPF工程中,当我们进行UI设计时,可以随意的将一个控件剪切/张贴到另外一个地方.操作方便的背后是什么在 ...