当前位置:网站首页>Implement the redis simple client customized based on socket
Implement the redis simple client customized based on socket
2022-06-24 20:22:00 【Maple honey pomelo tea】
One 、RESP agreement
First of all, understand ,Redis It's a CS framework Software for , Communication is generally divided into two steps ( barring pipeline and PubSub):
- client (client) To the server (server) Send a command
- The server parses and executes commands , Return the response result to the client Therefore, the format of the command sent by the client 、 The format of the server response result must have a specification , This specification is the communication protocol .
And in the Redis It is used in RESP(Redis Serialization Protocol) agreement :
- Redis 1.2 Version introduced RESP agreement
- Redis 2.0 In the version, it becomes the same as Redis The standard of server communication , be called
- RESP2 Redis 6.0 In the version , from RESP2 Upgrade to RESP3 agreement , Add more data types and support 6.0 New features -- Client cache
stay RESP in , Distinguish different data types by the characters of the first byte , Common data types include 5 Kind of :
- Single line string : The first byte is ‘+’ , Followed by a single line string , With CRLF( "\r\n" ) ending . Such as return "OK": "+OK\r\n"
- error (Errors): The first byte is ‘-’ , Same format as single line string , It's just that the string is an exception message , for example :"-Error message\r\n"
- The number : The first byte is ‘:’ , Followed by a string in numeric format , With CRLF ending . for example :":10\r\n"
- Multiline string : The first byte is ‘$’ , A string representing binary security , The biggest support 512MB: If the size is 0, Represents an empty string :"$0\r\n\r\n" If the size is -1, It means it doesn't exist :"$-1\r\n"

- Array : The first byte is ‘*’, Followed by the number of array elements , Keep up with the elements , The element data type is unlimited : for example

Two 、 simulation redis Client implementation
【 Response resolution request module 】
/**
* Parsing response request information
*
* @return Analysis results
*/
private static Object handleResponse() throws IOException {
// There are five ways to read data
int opt = READER.read();
switch (opt) {
case '+':// Single line string , Read single line information
return READER.readLine();
case '-':// Abnormal information , Exception returned from reading single line information
return READER.readLine();
case ':':// value type , Read single line
return Long.parseLong(READER.readLine());
case '*':
return readBulkString();
case '$':// Read multi line string
int len = Integer.parseInt(READER.readLine());
if (len == -1) {
return null;
} else if (len == 0) {
return "";
} else {
return READER.readLine();
}
default:
throw new RuntimeException(" Bad data format !");
}
}
/**
* Array result parsing
*
* @return
* @throws IOException
*/
private static Object readBulkString() throws IOException {
// Get array size
int size = Integer.parseInt(READER.readLine());
if (size <= 0) {
return null;
} else {
List<Object> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
result.add(handleResponse());
}
return result;
}
}【 Complete code 】
/**
* @Author Honey grapefruit tea
* @Date 2022/6/14 20:34
*/
public class MyRedisClient {
private static Socket socket;
private static PrintWriter WRITER;
private static BufferedReader READER;
private static BufferedReader KEYBOARD_INPUT;
private static final String INFO = "127.0.0.1:6379> ";
public static void main(String[] args) throws Exception {
try {
// Establishing a connection
// virtual machine IP Address :192.168.29.128
socket = new Socket("192.168.29.128", 6379);
// Get input stream 、 Output stream
WRITER = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
READER = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
// Keyboard input command
KEYBOARD_INPUT = new BufferedReader(new InputStreamReader(System.in));
// Carry out orders , At the same time, the result is analyzed
execute();
} catch (IOException e) {
e.printStackTrace();
} finally {
// Release the connection
try {
if (READER != null)
READER.close();
if (WRITER != null)
WRITER.close();
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Get keyboard input
*
* @return
* @throws Exception
*/
public static String getInput() throws Exception { // Keyboard information input
System.out.print(INFO);
return KEYBOARD_INPUT.readLine();
}
/**
* Carry out orders
*
* @throws IOException
*/
private static void execute() throws Exception {
while (true) {
// Get input command , Remove the first space
String string = getInput().trim();
// Parse command , Remove all spaces
String replace = string.replaceAll("\\s{1,}", "/");
//System.out.println(replace);
String[] strings = replace.split("/");
// Send a request
sendRequest(strings);
// Parsing response information
Object result = handleResponse();
if (result == null) {
System.out.println(getFormatResult("null", "warning"));
} else if (result.toString().startsWith("ERR")) {
System.out.println(getFormatResult(result.toString(), "error"));
} else {
System.out.println(getFormatResult(result.toString(), "info"));
}
}
}
/**
* Format output
*
* @param content result
* @param type type
* @return Format output
*/
private static String getFormatResult(String content, String type) {
if (type.equals("error")) {
return String.format("\033[%dm%s\033[0m", 31, content);
} else if (type.equals("info")) {
return String.format("\033[%dm%s\033[0m", 34, content);
} else if (type.equals("warning")) {
return String.format("\033[%dm%s\033[0m", 33, content);
} else {
return content;
}
}
/**
* Parsing response request information
*
* @return Analysis results
*/
private static Object handleResponse() throws IOException {
// There are five ways to read data
int prefix = READER.read();
switch (prefix) {
case '+':// Single line string , Read single line information
return READER.readLine();
case '-':// Abnormal information , Exception returned from reading single line information
return READER.readLine();
case ':':// value type , Read single line
return Long.parseLong(READER.readLine());
case '*':
return readBulkString();
case '$':// Read multi line string
int len = Integer.parseInt(READER.readLine());
if (len == -1) {
return null;
} else if (len == 0) {
return "";
} else {
return READER.readLine();
}
default:
throw new RuntimeException(" Bad data format !");
}
}
/**
* Array result parsing
*
* @return
* @throws IOException
*/
private static Object readBulkString() throws IOException {
// Get array size
int size = Integer.parseInt(READER.readLine());
if (size <= 0) {
return null;
} else {
List<Object> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
result.add(handleResponse());
}
return result;
}
}
/**
* Send request information
*
* @param args
*/
private static void sendRequest(String... args) {
// It is essentially an order --> set name XXXX
WRITER.println("*" + args.length);
for (String arg : args) {
WRITER.println("$" + arg.getBytes(StandardCharsets.UTF_8).length);
WRITER.println(arg);
}
// Empty buffer
WRITER.flush();
}
}3、 ... and 、 Effect display
【 simulation redis-cli】idear window
win The console output color is garbled , Color escape is not supported .

If articles are useful to you , Let's support them for three times !!!
边栏推荐
- Mq-2 smoke concentration sensor (STM32F103)
- The name of the button in the Siyuan notes toolbar has changed to undefined. Has anyone ever encountered it?
- Teach you how to cancel computer hibernation
- 建立自己的网站(14)
- 【CANN文档速递05期】一文让您了解什么是算子
- 两位湖南老乡,联手干出一个百亿IPO
- 16个优秀业务流程管理工具
- Redis installation of CentOS system under Linux, adding, querying, deleting, and querying all keys
- [cloud resident co creation] ModelBox draws your own painting across the air
- 【CANN文档速递04期】揭秘昇腾CANN算子开发
猜你喜欢

Map跟object 的区别

两位湖南老乡,联手干出一个百亿IPO

基于SSM的物料管理系统(源码+文档+数据库)

Openstack actual installation and deployment tutorial, openstack installation tutorial

Install the custom module into the system and use find in the independent project_ Package found

"Super point" in "Meng Hua Lu", is the goose wronged?

Audio and video 2020 2021 2022 basic operation and parameter setting graphic tutorial

Byte and Tencent have also come to an end. How fragrant is this business of "making 30million yuan a month"?

Two fellow countrymen from Hunan have jointly launched a 10 billion yuan IPO
![[go Language brossage] go from 0 to Getting started 4: Advanced use of slice, Primary Review and Map Getting started Learning](/img/3a/db240deb4c66b219ef86f40d4c7b7d.png)
[go Language brossage] go from 0 to Getting started 4: Advanced use of slice, Primary Review and Map Getting started Learning
随机推荐
Ribbon源码分析之@LoadBalanced与LoadBalancerClient
JVM tuning
Fundamentals of performance testing -- definitions of common terms
Steering gear control (stm32f103c8t6)
首个大众可用PyTorch版AlphaFold2复现,哥大开源OpenFold,star量破千
R for Data Science (notes) -- data transformation (used by filter)
redis数据结构之压缩列表
Jsup supports XPath
Teach you how to cancel computer hibernation
Some small requirements for SQL Engine for domestic database manufacturers
[R tidyverse] use of select verb
Huawei cloud modelarts has ranked first in China's machine learning public cloud service market for the fourth time!
Win7 10 tips for installing Office2010 five solutions for installing MSXML components
gateway
Coinbase将推出首个针对个人投资者的加密衍生产品
[video tutorial] functions that need to be turned off in win10 system. How to turn off the privacy option in win10 computer
unity实战之lol技能释放范围
Methods for comparing float types in the kernel
Unit actual combat lol skill release range
gateway