RESP是Redis序列化协议,Redis Serialization Protocol.是一种直观的文本协议,优点是实现过程异常简单,解析性能极好。
Redis传输协议将传输的结构数据分为5种最小单元类型,单元结束时统一加上回车换行符\r\n.
1.单行字符串以"+"符号开头;
2.多行字符串以"$"符号开头,后跟字符串长度。
3.整数值以":"符号开头,后跟整数的字符串形式。
4.错误消息以"-"符号开头。
5.数组以"*"开头,后跟数组的长度。
单行字符串hello world
+hello world \r\n
多行字符串hello world
$11\r\nhello world \r\n
整数1024
:1024 \r\n
错误
参数类型错误
-WRONGTYPE Operation against a key hoding the wrong kind of value \r\n
数组[1,2,3]
*3\r\n:1\r\n:2\r\n:3\r\n
NULL
NUll用多行字符串表示,长度是-1
$-1\r\n
空串
空串用多行字符串表示,长度0
*$0\r\n\r\n*
这里的两个\r\n之间隔的是空 串;
客户端–>服务端
客户端向服务端发送的指令只有一个种格式,多行字符串数组。
比如"set author codehole"
*3\r\n$3\r\nset\r\n$6\r\nauthor\r\n$8codehole\r\n
去掉\r\n,很容易阅读
*3
¥3
set
$6
author
$8
codehole
服务端–>客户端
服务端向客户端回复的响应迟滞多种数据结构,所以的响应都是5中基本类型的组合。
单行字符串响应
127.0.0.1:6379>set author codehole
OK
使用示例
有了报文格式,就可以利用socket和redis-server通讯了
如下(仅示范通讯,忽略socket/流的关闭)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class SocketRedisClient {
public static void main(String[] args) {
try {
Socket s = new Socket("192.168.208.138",6379);
String setCommand = "*3\r\n$3\r\nset\r\n$4\r\nname\r\n$4\r\njava\r\n";
String getCommand = "*2\r\n$3\r\nget\r\n$4\r\nname\r\n";
OutputStream os = s.getOutputStream();
InputStream is = s.getInputStream();
//set name java
os.write(setCommand.getBytes("UTF8"));
os.flush();
byte[] response = new byte[1000];
is.read(response);
System.out.println(new String(response));
//get author
os.write(getCommand.getBytes("UTF8"));
os.flush();
is.read(response);
System.out.println(new String(response));
} catch (IOException e) {
e.printStackTrace();
}
}
}
执行结果如下图