当前位置:网站首页>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 !!!
边栏推荐
- 用手机摄像头就能捕捉指纹?!准确度堪比签字画押,专家:你们在加剧歧视
- Steering gear control (stm32f103c8t6)
- 开放可编程基础设施(OPI)项目,重新定义DPU/IPU
- 用自身细胞作为原料,首例3D打印耳朵移植成功!未来可打印更复杂器官
- It is said that Tencent officially announced the establishment of "XR" department to bet on yuanuniverse; Former CEO of Google: the United States is about to lose the chip competition. We should let T
- You can capture fingerprints with a mobile camera?! Accuracy comparable to signature and monogram, expert: you are aggravating discrimination
- Error in Android connection database query statement
- 字节、腾讯也下场,这门「月赚3000万」的生意有多香?
- First understand redis' data structure - string
- [cann document express issue 05] let you know what operators are
猜你喜欢

16个优秀业务流程管理工具

Apple doesn't need money, but it has no confidence in its content

Uninstall tool v3.5.10.5670 single file portable official version

【Go語言刷題篇】Go從0到入門4:切片的高級用法、初級複習與Map入門學習

Bytebase rejoint la communauté de base de données open source d'alicloud polardb

Teach you how to view the number of connected people on WiFi in detail how to view the number of connected people on WiFi

Application practice | massive data, second level analysis! Flink+doris build a real-time data warehouse scheme

Dongyuhui is not enough to bring goods to "rescue" live broadcast

What are the functions of IBPs open source form designer?

对“宁王”边卖边买,高瓴资本“高抛低吸”已套现数十亿
随机推荐
Making startup U disk -- Chinese cabbage U disk startup disk making tool V5.1
[R tidyverse] use of select verb
Why is the executor thread pool framework introduced
Stackoverflow annual report 2022: what are developers' favorite databases?
Two solutions to the problem of 0xv0000225 unable to start the computer
Anti epidemic through science and technology: white paper on network insight and practice of operators | cloud sharing library No.20 recommendation
R for Data Science (notes) -- data transformation (used by filter)
Database index can improve query efficiency. Ask what will improve, what is the difference between inapplicable index and index use, and what will happen.
JVM tuning
gateway
IP address to integer
Audio and video 2020 2021 2022 basic operation and parameter setting graphic tutorial
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
Information theory of popular science Shannon
Uninstall tool v3.5.10.5670 single file portable official version
Methods for comparing float types in the kernel
Jd.com: how does redis implement inventory deduction? How to prevent oversold?
SQL export CSV data, unlimited number of entries
Bytebase 加入阿里云 PolarDB 开源数据库社区