【Reids通信协议】

Reids通信协议


第四章 Redis通信协议

概要

Redis通信

1. Redis通信协议

Redis 通信协议是客户端与 Redis 服务器之间进行交互的规则和约定;
简介:Redis 采用的是 RESP(Redis Serialization Protocol)协议,它是一种简单的文本协议,具有良好的可读性和可扩展性,能够高效地在客户端和服务器之间传输数据。
6.0以后新增RESP3协议,但是默认使用是RESP2。

/* 根据客户端协议版本发送响应 */
void addReply(client *c, robj *obj) {
    if (c->resp == 3) {
        /* 使用RESP3格式发送 */
        sendReplyUsingRESP3(c, obj);
    } else {
        /* 使用RESP2格式发送 */
        sendReplyUsingRESP2(c, obj);
    }
}
1.RESP2
/* RESP2 类型标识字符 */
#define REDIS_REPLY_STRING '+'
#define REDIS_REPLY_ERROR '-'
#define REDIS_REPLY_INTEGER ':'
#define REDIS_REPLY_BULK '$'
#define REDIS_REPLY_MULTI '*'

Redis 通过processInputBuffer()函数处理客户端输入,根据首个字节判断协议类型:

/* 处理客户端输入缓冲区 */
void processInputBuffer(client *c) {
    /* ... */
    if (c->resp == 3) {
        /* RESP3 解析逻辑 */
        if (processRESP3Packet(c) != C_OK) break;
    } else {
        /* RESP2 解析逻辑 */
        if (processRESP2Packet(c) != C_OK) break;
    }
    /* ... */
}
2.RESP2数据类型
  1. 简单字符串(Simple Strings)
    格式:以+开头,后跟字符串内容,以\r\n结尾
    用途:用于返回简单的成功消息,如OK。
    示例:“+OK\r\n”
  2. 错误(Errors)
    格式:以-开头后跟错误信息以\r\n结尾
    用途:返回命令执行过程中的错误。
    示例:-ERR unknown command ‘foobar’\r\n
  3. 整数数值(Integers)
    格式:以:开头,后跟整数值以\r\n结尾
    用途:返回计数结果(如INCR命令)或状态码(如EXISTS返回1或0)。
    示例:“:42\r\n”
  4. 多行字符串(Bulk Strings)
    格式:以$开头,后跟字符串长度(字节数),再以\r\n分隔接着是实际字符串内容,最后以\r\n结尾。,
    在这里插入图片描述
    在这里插入图片描述
    示例:
    字符串hello:“$5\r\nhello\r\n”
    空字符串:“$0\r\n\r\n”
  5. 数组(Arrays)
    格式:
    以*开头后跟数组元素个数,以\r\n分隔,每个元素遵循上述任意数据类型格式。
    空数组:“*0\r\n”
    空值数组:“*-1\r\n”(表示NULL数组)。
    示例:

    在这里插入图片描述
3.基于socket的自定义客户端

基于socket的自定义客户端

   private static Socket socket;
    private static PrintWriter writer;
    private static BufferedReader reader;


    public static void main(String[] args) {

            try {
                //1. 建立连接
                socket = new Socket("localhost",6379);
                //2. 获取输入/出流
                writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));

                //3. 请求
                sendRequest("set","name","HelloWorld");
                sendRequest("mget","name","msg");
                //4. 响应
                Object response = response();
                System.out.println(response);
            } catch (IOException e) {
                e.printStackTrace();
            }finally {

        }
    }
    private static void sendRequest(String ... args){
        writer.println("*" +args.length);
        for (String arg : args) {
            writer.println("$" + arg.getBytes(StandardCharsets.UTF_8).length);
            writer.println(arg);
        }
        writer.flush();
    }
    private static Object response() throws IOException {
        int read = reader.read();
        switch (read){
            case '+':
                return reader.readLine();
            case '-':
                throw new RuntimeException(reader.readLine());
            case ':':
                return Long.parseLong(reader.readLine());
            case '$':
                int len = Integer.parseInt(reader.readLine());
                if (len == -1 ){
                    return null;
                }
                if (len == 0){
                    return "";
                }
                return reader.readLine();
            case '*':
                int l = Integer.parseInt(reader.readLine());
                if (l <= 0) {
                    return null;
                }
                ArrayList<Object> list = new ArrayList<>(l);
                for (int i = 0; i < l; i++) {
                    list.add(response());
                }

            default:
                throw new RuntimeException("ERROR ");
        }
    }

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值