1:模拟redis-server
package com.haolin.java.demos.jedis;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
public class MockRedisServer {
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
// 模拟redis-server服务
ServerSocket serverSocket = new ServerSocket(6399);
InputStream inputStream = serverSocket.accept().getInputStream();
byte[] bs = new byte[1024];
inputStream.read(bs);
// 打印请求信息
System.out.println(new String(bs, "UTF-8"));
}
}
2.使用官方Jedis发送请求,抓取报文信息
public void testProtocol() {
// 使用刚刚开启的模拟服务
Jedis jedis = new Jedis("redis://localhost:6399");
jedis.set("iname", "zhanghaolin");
// jedis.get("iname");
}
3. 分析报文信息,解密 protocol
// 控制台输出
// set("iname", "zhanghaolin")
*3
$3
SET
$5
iname
$11
zhanghaolin
// 控制台输出
// get("iname")
*2
$3
GET
$5
iname
4.手写Jedis传输层
package com.haolin.java.demos.jedis;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* function: Jedis传输层
*
* @author zhanghaolin
* @date 2018年12月26日上午10:44:30
*/
public class Jedis {
private Socket socket;
private String host;
private Integer port;
public Jedis(String host, Integer port) {
this.host = host;
this.port = port;
connect();
}
public void connect() {
if (!isConnected()) {
try {
socket = new Socket(host, port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public boolean isConnected() {
return socket != null && socket.isBound() && !socket.isClosed() && socket.isConnected()
&& !socket.isInputShutdown() && !socket.isOutputShutdown();
}
public String set(String key, String value) {
try {
Protocol.sendCommand(socket.getOutputStream(), Protocol.Command.SET, SafeEncode.castValue(key),
SafeEncode.castValue(value));
return Protocol.reply(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String get(String key) {
try {
Protocol.sendCommand(socket.getOutputStream(), Protocol.Command.GET, SafeEncode.castValue(key));
return Protocol.reply(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
package com.haolin.java.demos.jedis;
/**
* function: encode
*
* @author Administrator
* @date 2018年12月26日上午11:41:10
*/
public class SafeEncode {
public static byte[] castValue(String value) {
if (value == null)
value = "";
return value.getBytes();
}
}
5:手写Jedis协议层
package com.haolin.java.demos.jedis;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* function: Jedis协议层
*
* @author zhanghaolin
* @date 2018年12月26日上午10:44:30
*/
public class Protocol {
private static final String BULK_STRINGS = "$";
private static final String ARRAY = "*";
private static final String BLANK = "\r\n";
public static enum Command {
SET, GET
}
public static void sendCommand(OutputStream outputStream, Protocol.Command commond, byte[]... bs) {
String protocolMessage = protocolMessage(commond, bs);
try {
outputStream.write(protocolMessage.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public static String reply(InputStream inputStream) {
byte[] bs = null;
try {
bs = new byte[1024];
inputStream.read(bs);
} catch (IOException e) {
e.printStackTrace();
}
return new String(bs);
}
private static String protocolMessage(Protocol.Command commond, byte[]... bs) {
StringBuffer message = new StringBuffer();
message.append(ARRAY).append(bs.length + 1).append(BLANK);
message.append(BULK_STRINGS).append(commond.name().length()).append(BLANK);
message.append(commond).append(BLANK);
for (int i = 0; i < bs.length; i++) {
message.append(BULK_STRINGS).append(bs[i].length).append(BLANK);
message.append(new String(bs[i])).append(BLANK);
}
return message.toString();
}
}
6:演示执行 set,get
package com.jedis.test;
import org.junit.Test;
import com.haolin.java.demos.jedis.Jedis;
public class JedisTest {
@Test
public void testJedis() {
// 使用我们手写的jedis com.haolin.java.demos.jedis.Jedis
Jedis jedis = new Jedis("127.0.0.1", 6379);
String setReply = jedis.set("name", "Hello uuimi");
System.out.println("set name : " +setReply);
System.out.println("=====================================");
String string = jedis.get("name");
System.out.println("get name: ");
System.out.println(string);
}
}
控制台输出:
set name : +OK
get name:
$11
Hello uuimi