引言
本文章为了复习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
还没有评论,来说点什么吧。