From eaff064342ab2baa09cc2ea15f11726c666c3407 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 3 Jul 2026 17:51:51 +0200 Subject: basic dictionary server with set and get todo: mutex to protect server --- .gitignore | 25 ++++++++++++++++++++ main.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index e69de29..f6501fa 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,25 @@ +# Binaries and executables +# (This catches the compiled files generated by 'go build') +*.exe +*.exe~ +*.dll +*.so +*.dylib +bin/ +__debug_bin + +# OS generated files +.DS_Store +Thumbs.db + +# IDE specific files +.idea/ +.vscode/ +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# Optional: If you use a .env file for local configuration/ports +.env diff --git a/main.go b/main.go index b7d2a32..ece44a2 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,82 @@ package main -import "fmt" +import ( + "bufio" + "fmt" + "net" + "os" + "strings" +) + +var database map[string]string func main() { - fmt.Println("Hello, World!") + database = make(map[string]string) + + listener, err := net.Listen("tcp", ":6379") + if err != nil { + fmt.Println("error starting server: ", err) + os.Exit(1) + } + defer listener.Close() + fmt.Println("Redis clone listening on port 6379...") + + for { + conn, err := listener.Accept() + if err != nil { + fmt.Println("Error accepting connection:", err) + continue + } + go handleConnection(conn) + } +} + +func handleGet(conn net.Conn, key string) { + value, exists := database[key] + if exists { + // Redis protocol format for a string reply + conn.Write([]byte("+" + value + "\r\n")) + } else { + // Redis protocol format for a Nil/Null response + conn.Write([]byte("$-1\r\n")) + } +} + +func handleSet(conn net.Conn, key, value string) { + database[key] = value + conn.Write([]byte("+OK\r\n")) } + +func handleConnection(conn net.Conn) { + defer conn.Close() + fmt.Println("Client connected:", conn.RemoteAddr()) + + reader := bufio.NewReader(conn) + for { + message, err := reader.ReadString('\n') + if err != nil { + fmt.Println("Client disconnected:", conn.RemoteAddr()) + return + } + + message = strings.TrimSpace(message) + + fmt.Printf("Received: %s\n", message) + + args := strings.Fields(message) + if len(args) == 0 { + continue + } + + command := strings.ToUpper(args[0]) + + switch { + case command == "GET" && len(args) == 2: + handleGet(conn, args[1]) + case command == "SET" && len(args) == 3: + handleSet(conn, args[1], args[2]) + default: + conn.Write([]byte("-ERR unknown command or wrong arguments\r\n")) + } + } +} \ No newline at end of file -- cgit v1.2.3