记踩 redis RESP 协议的一次坑

今天踩了redis的一个大坑。就是关于 RESP 协议的。

RESP

RESP 本身基于 TCP 双工通信,在应用层采取的就是 RESP 协议进行数据交互。协议本身内容非常简单。

发送请求:SET key value

*3
$3
SET
$3
key
$5
value
  • 开头固定* number,number 表示:命令 + 参数,一共有多少个部分。比如上述案例的*3表示有3部分——①SET②key③value
  • 每部分开头就是$ number,number表示:该部分有多少个字符。比如value部分的前面的$5,就表示该部分有5个字符。

但是实际上发往 redis 的内容实际上是:

*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue
注意大坑

这里有个大坑:每一部分的换行符固定是\r\n,而非\n

实践证明:这个地方固定式\r\n,而不依赖于具体的操作系统。

亲手测试:

linux 下,vim 一个 java 脚本,写入:

import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
 * @author yq
 * @version v1.0 2023-01-19 9:28 PM
 */
public class TestMain {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("192.168.204.140", 6379);
            OutputStream os = socket.getOutputStream();
            os.write("*3\n$3\nSET\n$7\nT-WYQ-T\n$3\n323\n".getBytes(StandardCharsets.UTF_8));
            os.flush();

            socket.close();
        }catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

注意中间换行符是\n,然后javac编译,然后java命令跑一把,把命令用socket发出去了。

这样再开一个 ssh 窗口,然后nc 192.168.204.140(自己的虚拟机) 6379,然后直接GET T-WYQ-T ,发现结果是-1。

然后把换行符换成\r\n,重新重复上述操作,就发现能GET到了!

其他证明

查看 jedis 源码,发现源码写死了,固定就是CRLF。(无论哪个系统,jar包里面肯定是写死的)

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值