Loading... # 引言 本文章为了复习redis和java的socket通讯,针对本篇文章,大体上需要以下工具(软件)。 * telnet 或 nc * jdk * redis-server # redis客户端原理 通过`nc`命令连接redis服务,`nc 127.0.0.1 6379` 简单的执行一些命令,比如`keys *` 和 `set a 1` ![大概返回值](https://www.zunmx.top/usr/uploads/2023/07/3258114039.png) ![大概返回值](https://www.zunmx.top/usr/uploads/2023/07/1844261202.png) 多谢几条之后,就可以猜到解析方法,最后用代码实现解析就好了。 `*[num]`指的是有几行 `$[num]`指的是键有几个字符 `+OK`表示执行成功 `:[num]`表示受影响的个数 # java代码 ## 连接工具类 ```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)); } } ``` ## 主入口 ```java 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("连接失败"); } } } ``` # 截图 ![运行结果](https://www.zunmx.top/usr/uploads/2023/07/2879554279.png) # 总结 其实这只是一个小玩具,实际上已经有封装好的redis连接驱动,我们直接用就好了,也没必要自己去手写驱动。 当然,本代码也只是一个小demo,没有经过严格的测试,某些场景下可能并不适用,也仅为了提供一个思路。 > 最好定时执行PING命令,以免连接被中断。 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏