java socket 简单实现redis连接驱动

引言

本文章为了复习redis和java的socket通讯,针对本篇文章,大体上需要以下工具(软件)。

  • telnet 或 nc
  • jdk
  • redis-server

redis客户端原理

通过nc命令连接redis服务,nc 127.0.0.1 6379
简单的执行一些命令,比如keys * 和 set a 1
大概返回值
大概返回值

多谢几条之后,就可以猜到解析方法,最后用代码实现解析就好了。

*[num]指的是有几行
$[num]指的是键有几个字符
+OK表示执行成功
:[num]表示受影响的个数

java代码

连接工具类

package top.zunmx.common;

import java.io.*;
import java.net.Socket;
import java.net.SocketAddress;

public class Connection {
    private static Connection connection;
    private static Socket socket;

    public static Connection getInstance() {
        // 双重检查锁,保证单例
        if (connection == null) {
            synchronized (Connection.class) {
                if (connection == null) {
                    connection = new Connection();
                }
            }
        }
        return connection;
    }

    public boolean link(String url, Integer port) {
        try {
            socket = new Socket(url, port); // 创建socket连接
            socket.setSoTimeout(5000);
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    public String exchange(String msg) {
        try {
            OutputStream os = socket.getOutputStream(); // 输出流
            InputStream is = socket.getInputStream(); // 输入流
            PrintStream ps = new PrintStream(os);
            StringBuilder sb = new StringBuilder();
            ps.println(msg);
            ps.flush();
            int cur = 0;
            int read = is.read();
            int total = is.available();
            sb.append((char) read);
            while (cur < total) {
                cur++;
                read = is.read();
                sb.append((char) read);
            } // 这里也可以用缓冲区
            return sb.toString();
        } catch (Exception e) {
            return "*0\r\n";
        }
    }

    public String formatter(String str) { //自定义一个格式化方法
        StringBuilder sb = new StringBuilder();
        int startIDX = 0;
        if (str.startsWith("*")) {
            startIDX = 2;
        } else if (str.startsWith("$")) {
            startIDX = 1;
        } else if (str.startsWith(":")) {
            return str.trim().replace(":", "");
        }
        String[] split = str.split("\r\n");
        int line = split.length;
        for (int i = startIDX; i < line; i += 2) {
            sb.append(split[i]).append("\r\n");
        }
        return sb.toString().trim();
    }
}

命令封装

实际上就是redis-cli中执行的命令,这里通过socket封装后的模块进行发送指令

package top.zunmx.common;

public class Utils {
    private static Connection connection = Connection.getInstance();

    public static boolean setString(String key, String value) {
        String exchange = connection.exchange(String.format("set %s %s", key, value));
        return "+OK".equals(exchange.trim());
    }

    public static String getString(String key) {
        String exchange = connection.exchange(String.format("get %s", key));
        return connection.formatter(exchange);
    }

    public static int del(String key) {
        String exchange = connection.exchange(String.format("del %s", key));
        return Integer.parseInt(connection.formatter(exchange));
    }
}

主入口

package top.zunmx;

import top.zunmx.common.Connection;
import top.zunmx.common.Utils;


public class main {
    public static void main(String[] args) {
        Connection instance = Connection.getInstance();
        boolean link = instance.link("127.0.0.1", 6379);
        if (link) {
            System.out.println("redis连接成功");
            System.out.println("有以下keys:\r\n" + instance.formatter(instance.exchange("keys *")));
            System.out.println("设置字符串:" + (Utils.setString("a", "123456") ? "成功" : "失败"));
            System.out.println("获取刚刚设置的字符串:" + Utils.getString("a"));
            System.out.println("删除刚刚的a:" + Utils.del("a"));
            System.out.println("再删除a:" + Utils.del("a"));

        } else {
            System.out.println("连接失败");
        }
    }
}

截图

运行结果

总结

其实这只是一个小玩具,实际上已经有封装好的redis连接驱动,我们直接用就好了,也没必要自己去手写驱动。
当然,本代码也只是一个小demo,没有经过严格的测试,某些场景下可能并不适用,也仅为了提供一个思路。

最好定时执行PING命令,以免连接被中断。

评论 0

还没有评论,来说点什么吧。

提交后需要审核才会公开。