转自:https://www.jianshu.com/p/daa3cb672470
Redis服务器与客户端通过RESP(REdis Serialization Protocol)协议通信。
RESP协议支持的数据类型
以下例子都是展示redis返回的真实值,在redis客户端会把返回数据的前缀去掉
Simple String
第一个字节以+
开头,随后紧跟内容字符串(不能包含CR
LF
),最后以CRLF
结束。很多Redis命令执行成功时会返回"OK","OK"就是一个Simple String
:
"+OK\r\n"
Error
的结构与Simple String
很像,但是第一个字节以-
开头:
"-ERR unknown command 'foobar\r\n'"
-
符号后的第一个单词代表错误类型,ERR代表一般错误,WRONGTYPE代表在某种数据结构上执行了不支持的操作。
Integer
第一个字节以:
开头,随后紧跟数字,以CRLF
结束:
":1000\r\n"
很多Redis命令会返回Integer
,例如INCR
LLEN
等。
Bulk String
是一种二进制安全的字符串结构,整个结构包含两部分。第一部分以$
开头,后面紧跟字符串的字节长度,CRLF
结尾。第二部分是真正的字符串内容,CRLF
结尾,最大长度限制为512MB。一个Bulk String
结构的"Hello World!"是:
"$12\\r\\nHello World!\\r\\n"
空字符串是:
"$0\\r\\n\\r\\n"
nil是:
"$-1\\r\\n"
Array
也可以看成由两部分组成,第一部分以*
开头,后面紧跟一个数字代表Array
的长度,以CRLF
结束。第二部分是每个元素的具体值,可能是Integer
,可能是Bulk String
。Array
结构的["hello", "world"]是:
"*2\\r\\n$5\\r\\nhello\\r\\n$5\\r\\nworld\\r\\n"
空Array
:
"*-1\\r\\n"
要注意一点,RESP的数据类型和redis的数据类型不一样,他们之间的关系是在数据传输中RESP的数据类型能够表达所有的redis数据类型,比如redis中有个hash数据类型
127.0.0.1:6379> HMSET runoobkey name "redis tutorial" description "redis basic commands for caching" likes 20 visitors 23000 OK 127.0.0.1:6379> HGETALL runoobkey 1) "name" 2) "redis tutorial" 3) "description" 4) "redis basic commands for caching" 5) "likes" 6) "20" 7) "visitors" 8) "23000"这里RESP就是用Array来表达hash,
通过RESP协议与服务端通信
了解了Redis协议的基本数据类型,就可以通过Socket与Redis Server进行通信:
package me.likeyao.yingzong.example; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.charset.Charset; /** * Created by yingzong on 16/6/15. */ public class SimpleProtocol { public static void main(String[] args) throws Exception{ Socket socket = new Socket(); //TIME_WAIT状态下可以复用端口 socket.setReuseAddress(true); //空闲时发送数据包,确认服务端状态 socket.setKeepAlive(true); //关闭Nagle算法,尽快发送 socket.setTcpNoDelay(true); //调用close方法立即关闭socket,丢弃所有未发送的数据包 socket.setSoLinger(true, 0); //连接server socket.connect(new InetSocketAddress("localhost", 6379), 3000); //设置读取时超时时间 socket.setSoTimeout(3000); OutputStream os = socket.getOutputStream(); /** * SET 命令 * 协议: array 3个元素 SET simpleKey simpleValue */ os.write(getBytes("*3\\r\\n$3\\r\\nSET\\r\\n$9\\r\\nsimpleKey\\r\\n$11\\r\\nsimpleValue\\r\\n")); os.flush(); InputStream is = socket.getInputStream(); /** * 解析SET命令的返回结果 */ String result = analysisResult(is); System.out.println("SET command response : " + result); System.out.println(); /** * GET 命令 * 协议: array 2个元素 GET simpleKey */ os.write(getBytes("*2\\r\\n$3\\r\\nGET\\r\\n$9\\r\\nsimpleKey\\r\\n")); os.flush(); /** * 解析GET命令返回结果 */ String value = analysisResult(is); System.out.println("GET command response : " + value); is.close(); os.close(); socket.close(); } /** * 解析返回结果 * @param is * @return * @throws Exception */ private static String analysisResult(InputStream is) throws Exception{ /** * 第一个字节指定返回的数据结构类型 */ byte type = (byte)is.read(); System.out.println("response type is : " + (char)type); if(type == '+'){ //Simple String类型 return readCRLF(is); }else if(type == '$'){ //Bulk String类型 int len = readIntCRLF(is); System.out.println("$ value len : " + len); return readFixedLen(is, len); } return null; } /** * 读取int值,直到遇到CRLF * @param is * @return * @throws Exception */ private static int readIntCRLF(InputStream is) throws Exception{ return Integer.parseInt(readCRLF(is)); } /** * 读取字符串,直到遇到CRLF * @param is * @return * @throws Exception */ private static String readCRLF(InputStream is) throws Exception{ byte b = (byte)is.read(); StringBuilder sb = new StringBuilder(); //不是最后一个输入字节时 while(b != -1){ //判断是否是CR,如果不是加入sb中 if(b != '\\r'){ sb.append((char)b); }else{ //如果是CR,继续读取一个字节,如果不是LF,报错 byte oneMore = (byte)is.read(); if(oneMore != '\\n'){ throw new RuntimeException("CRLF error!"); }else{ break; } } b = (byte)is.read(); } return sb.toString(); } /** * 读取固定字节长度的字符串 * @param is * @param len * @return * @throws Exception */ private static String readFixedLen(InputStream is, int len) throws Exception{ byte[] bytes = new byte[len]; for(int i = 0; i < len; i++){ bytes[i] = (byte)is.read(); } //CR is.read(); //LF is.read(); return new String(bytes, "UTF-8"); } private static byte[] getBytes(String str) throws Exception{ return str.getBytes(Charset.forName("UTF-8")); } } => response type is : + SET command response : OK response type is : $ $ value len : 11 GET command response : simpleValue
代码执行了两个命令:
SET simpleKey "simpleValue" => "OK" GET simpleKey => "simpleValue"
analysisResult方法目前只支持了+
$
两种格式的解析,其他格式解析方式类似,就不一一实现了。
相关推荐
**Redis桌面管理器RESP.app详解** Redis是一款高性能的键值对数据库,广泛应用于缓存、消息中间件等场景。为了方便开发者对Redis进行管理和操作,出现了各种图形化用户界面(GUI)工具,其中就包括了RESP.app,它...
**Redis可视化工具RESP 2022.1.0.0 GUI详解** Redis,全名Remote Dictionary Server,是一款开源、高性能、支持网络、基于键值对的数据存储系统。在开发和运维过程中,为了方便地管理和操作Redis服务器,可视化工具...
标题提到的"免费Redis图形化界面(RESP):resp-2022.5.zip"是一个关于Resp的更新版本,其中包含了一款名为"resp-2022.5.0.0.exe"的可执行文件,这是RESP图形化管理工具的安装程序。用户可以通过这个程序在Windows...
描述中提到的“RESP_app”是一个Redis响应协议(REdis Simple String Protocol)的应用程序,可能是一个图形用户界面(GUI)工具,用于管理和操作Redis服务器。RESP是Redis默认的通信协议,它使得客户端与服务器之间...
在下载并安装 resp-2022.5.0.0.exe 文件后,只需按照安装向导的指示完成安装过程,然后启动 Redis Desktop Manager,即可开始你的 Redis 管理之旅。请注意,为了确保系统的安全性,务必备份重要数据,并定期更新软件...
本资料"mvn_resp.rar"聚焦于Maven的响应式编程(Reactive Programming)特性,旨在帮助开发者深入理解并熟练运用这一技术。以下是关于Maven响应式编程的详细讲解。 一、Maven概述 Maven是由Apache软件基金会开发的...
最新版本 Redis 可视化客户端软件,RedisDesktopManager 最新版本 RESP.app 2022.5 GUI for Redis,Windows 64 位最新版本,安全可靠,下载直接安装可用。
rdm resp redis resp-2022.5.1 RedisDesktopManager 2022.5.1
redis之resp界面连接
4. 使用Redis Desktop Manager:现在,你可以打开下载的"RESP.app_RedisDesktopManager_2022.5.exe"文件,安装并启动Redis Desktop Manager。在应用程序中,输入Redis服务器的IP地址(对于本地安装通常是`127.0.0.1`...
在使用Apache HttpClient进行HTTP通信时,可能会遇到"HttpClient问题:The server failed to respond with a valid HTTP resp"这样的异常。这个错误通常表示服务器未能返回一个有效的HTTP响应,这可能是由多种原因...
RedisDesktopManager 2022.0.0.0
99,00¥下载,无偿分享给大家 Redis Desktop Manager – Redis可视化管理工具 2022.3 windows 最新版本redis客户端管理工具 windows 64位 已编译好的安装程序(编译之路漫长,此程序由官方编译) ...
RedisDesktopManager 2022.1.0.0
RedisDesktopManager 2022.2.0.0
99,00¥下载,无偿分享奉献给大家 Redis Desktop Manager – Redis可视化管理工具 2022.3 windows 最新版本redis客户端管理工具 windows 64位 已编译好的安装程序(编译之路漫长,此程序由官方编译) ...
已经编译好的windows x64位版本的redis desktop manager
RedisDesktopManager 2022.4.2.0
截至2024年3月14日,我无法直接提供resp-2022.2这个特定版本的Redis,因为Redis官方发布版本格式通常是`redis-x.y.z.tar.gz`,其中x、y、z代表主版本号、次版本号和修订版本号。 如果您想安装Redis的某个特定历史...
RedisDesktopManager 2022.1.1.0.0