c++ redis客户端, 带详情输入输出

文章目录

    • 使用方法
    • 输入
    • 输出解释
    • 代码
    • 输出

使用方法

g++ main.cpp
./a.out -h 127.0.0.1 -p 6379

输入

一行内输入 redis 命令
keys*
set name
get name
等等 redis命令

输出解释

输入redis: redis收到的redis协议的数据
human输入: 你输入的原始字符
redis输出: redis返回的基于 redis协议的数据
human输出: 稍微处理过的 redis放回的数据

代码

#include <iostream>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <vector>
#include <unistd.h>
#include <sstream>
#include <getopt.h>
using namespace std;

string ip = "127.0.0.1";
int p = 6379;

class TcpCli {
public:
    string ip;
    int port;
    int fd;

    explicit TcpCli(const string& ip = "127.0.0.1", int port = 80) {
        this->ip = ip;
        this->port = port;
        fd = -1;
    }

    ~TcpCli() {
        if (fd != -1) {
            close(fd);
        }
    }

     bool connect() {
        // 电话号码
        fd = socket(AF_INET, SOCK_STREAM, 0);
        if (fd == -1) {
            return false;
        }
        // 拨号
        sockaddr_in saddr{};
        saddr.sin_family = AF_INET;
        saddr.sin_port = htons(port);
        saddr.sin_addr.s_addr = inet_addr(ip.c_str());
        int ret = ::connect(fd, (sockaddr *) &saddr, sizeof(saddr));
        if (ret == -1) {
            return false;
        }
        return true;
    }

    int send(const string& data) {
        return ::send(fd, data.c_str(), data.size(), 0);
    }

    int recv(string& data) {
        char buf[1024];
        int ret = ::recv(fd, buf, sizeof(buf), 0);
        if (ret > 0) {
            data.assign(buf, ret);
        }
        return ret;
    }

};

class RedisRequestProtocol {
public:
    static string makeRequest(const vector<string> &args) {
        string res = "*" + to_string(args.size()) + "\r\n";
        res += "$" + to_string(args[0].size()) + "\r\n";
        res += args[0] + "\r\n";
        for (int i = 1; i < args.size(); i++) {
            res += "$" + to_string(args[i].size()) + "\r\n";
            res += args[i] + "\r\n";
        }
        return res;
    };

public:
    static string set(const string &key, const string &value) {
        return makeRequest({"set", key, value});
    }

    static string get(string key) {
        return makeRequest({"get", key});
    }
};

string beautify(const string& data) {
    string res;
    string res2;
    for (int i = 0; i < data.size(); i++) {
        if (data[i] != '\r' && data[i] != '\n') {
            res += data[i];
            res2 += data[i];
            continue;
        }
        if (data[i] == '\r') {
          res += "\\r\\n";
          i++;
        }
    }
    return res;
}

string deleteSome(const string& data, char ch) {
    string res;
    for (int i = 0; i < data.size(); i++) {
        if (data[i] == ch) {
            int pos = data.find("\r\n", i);
            i = pos + 1;
        } else {
            res += data[i];
        }
    }
    return res;
}

string human(const string& data) {
    if (data.empty()) {
        return data;
    }
    if (data[0] == '-') {
        return data.c_str() + 1;
    }
    string res;
    // 删掉多行字符串标记
    string temp = deleteSome(data, '$');
    // 删去数组标记
    temp = deleteSome(temp, '*');
    return res = temp;
}

void tishi(const string& addr, string op = "输入redis:") {
    cout << op << addr;
}

class RedisCli {
public:
    TcpCli cli;
    string addr;
    RedisRequestProtocol requestProtocol;

    RedisCli(string ip = "127.0.0.1", int port = 6379) : cli(ip, port) {
        addr = ip + ":" + to_string(port);
        if (!cli.connect()) {
            cout << "connect error" << endl;
            exit(-1);
        }
    }

    template<class ...Args>
    void runCommand(const Args... args) {
        string request = requestProtocol.makeRequest({args...});
        tishi(addr + "> ");
        cout << beautify(request) << endl;
        auto ret = cli.send(request);
        if (ret == -1) {
            throw "send error";
        }
        string data;
        ret = cli.recv(data);
        if (ret == -1) {
            throw "recv error";
        }
        tishi(addr + "> ", "redis输出:");
        cout << beautify(data)<< endl;
        tishi(addr + ">\n", "human输出:");
        cout << human(data);
    }
};


void parseArgv(int argc, char** argv) {
    int option;
    while((option=getopt(argc, argv, "h:p:"))) {
        switch(option) {
            case 'h':
                ip = optarg;
                break;
            case 'p':
                p = atoi(optarg);
                break;
            default:
                return;
        }
    }
}

int main(int argc, char** argv) {
    parseArgv(argc, argv);
    RedisCli cli(ip, p);
    string command;
    cout << "*********************为了看的清楚, 我们把返回数据的\\r\\n打出来了, 并分行显示*********************" << endl;
    while (true) {
        tishi(cli.addr + "> ", "human输入:");
        if (!getline(cin, command) || command.empty()) {
            continue;
        }
        if (command == "q" || command == "Q") {
            break;
        }
        stringstream ss(command);
        vector<string> args;
        string arg;
        while(ss >> arg) {
            args.push_back(arg);
        }
        cli.runCommand(args);
    }

}

输出

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/227953.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Ambari】Python调用Rest API 获取YARN HA状态信息并发送钉钉告警

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&am…

SSL证书代理

众所周知&#xff0c;SSL证书已经成为当下网络安全中不可或缺的一个环节&#xff0c;对于很多开发公司来说&#xff0c;给自己的客户提供SSL证书安全服务也是最为基础的。 但是目前市面上像阿里云之类的证书服务商对于开发公司需要的证书并没有太大的一个优惠政策&#xff0c;给…

Java第二十一章总结

网络编程三要素 ip地址&#xff1a;计算机在网络中的唯一标识 端口&#xff1a;应用程序在计算机中唯一标识 协议&#xff1a;通信协议&#xff0c;常见有UDP和TCP协议 InetAddress类 表示Internet协议地址 //返回InetAddress对象 InetAddress byName InetAddress.…

2023年4K投影仪怎么选?极米H6 4K高亮版怎么样?

随着人们生活水平的不断提升&#xff0c;投影仪也逐渐成为了家家户户的必备家居好物。近十年来&#xff0c;中国投影仪市场规模增长数倍&#xff0c;年均增长率大幅提高。从近10年的发展趋势来看&#xff0c;投影仪行业处于高速发展期。 此前&#xff0c;极米科技推出的极米H6…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑气电联合需求响应的气电综合能源配网系统协调优化运行》

这个标题涉及到一个涉及气体&#xff08;天然气&#xff09;和电力的综合能源配网系统&#xff0c;并且强调了考虑气电联合需求响应的协调优化运行。让我们逐步解读&#xff1a; 气电综合能源配网系统&#xff1a; 这指的是一个结合了气体&#xff08;通常是天然气&#xff09;…

LangChain 23 Agents中的Tools用于增强和扩展智能代理agent的功能

LangChain系列文章 LangChain 实现给动物取名字&#xff0c;LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄LangChain 4用向量数据库Faiss存储&#xff0c;读取YouTube的视频文本搜索I…

Python 从入门到精通 学习笔记 Day02

Python 从入门到精通 第二天 今日目标 字符串基本操作、字符串序列操作、输入输出函数 字符串内置方法、运算符、练习之前学习的内容 一、字符串基本操作 在Python中&#xff0c;字符串的转义是指在字符串中使用特殊的字符序列来表示一些特殊字符。 在Python中&#xff0c;字…

Java实现TCP一对一通信,实现UDP群聊通信

TCP一对一通信: 实现服务端对话框&#xff1a; 其中可自由更改对话框的样式 import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class QqMain extends JFrame implements ActionListener{public static void …

可视化监控/安防视频云平台公共区域人员行为安全监控方案

大家在浏览新闻时&#xff0c;经常会看到某某地区有人员摔倒&#xff0c;长时间无人发现或人员闯入某危险区域管理人员未及时劝离&#xff0c;导致发生了意外事故的新闻。由于人力资源和人为巡检能力有限&#xff0c;在很多公共区域无法及时检测人员行为从而导致危险发生。为确…

千万别碰SLAM,会变得不幸--下阙

0.书接上回 之前的工作内容总结: 1.学习了回环检测的流程,还学习了DLoopDetector算法。 2.修改了vins-mono将匹配和回环到的图片进行保存。 3.找到了一个不是办法的办法来代替pr曲线,指定范围作真值。 4.大致了解了DTW地磁匹配算法,关键点是要划分第一圈和第二圈的界限。 …

如何还原分区? 分区和卷恢复的详细步骤

​我们曾介绍过用傲梅轻松备份将分区备份为镜像文件的方法。那备份好的分区如何恢复呢&#xff1f;同样&#xff0c;使用傲梅轻松备份也能实现分区的还原。以下是分区还原的步骤&#xff1a; 提示&#xff1a;提前使用傲梅轻松备份创建一个可启动U盘。 1. 准备U盘启动…

QT----自定义信号和槽

第二天 2.1自定义信号和槽 新建一个Qtclass 自定义信号&#xff1a;返回值是void &#xff0c;只需要声明&#xff0c;不需要实现&#xff0c;可以有参数&#xff0c;可以重载 自定义槽&#xff1a;返回值void &#xff0c;需要声明&#xff0c;也需要实现&#xff0c;可以有…

学习Opencv(蝴蝶书/C++)相关1——4.图形和大型数组类型

文章目录 1. 多维度数组和多通道数组区别2. NAryMatIterator详解2.1 介绍2.2 dispatch和SIMD(OpenCV和numpy)2.2.1 OpenCV的2.2.2 numpy的2.2.3 OpenCV文档搜索2.3 调用指令集对代码进行优化2.4 NAryMatIterator理解2.4.1 plane和连续2.4.2 构造函数和迭代2.5 NAryMatIterato…

快速认识什么是:Kubernetes

每次谈到容器的时候&#xff0c;除了Docker之外&#xff0c;都会说起 Kubernetes&#xff0c;那么什么是 Kubernetes呢&#xff1f;今天就来一起学快速入门一下 Kubernetes 吧&#xff01;希望本文对您有所帮助。 Kubernetes&#xff0c;一种用于管理和自动化云中容器化工作负…

从传统到胜利:广汽集团汽车产业创新之旅

置身于汽车行业百年未有之大变局&#xff0c;作为传统车企中的排头兵&#xff0c;广汽创新可圈可点&#xff0c;广汽近年来取得了骄人业绩&#xff0c;不论是整体产销规模&#xff0c;还是新能源汽车产业化、新技术领域开拓等&#xff0c;都呈现节节攀升的局面。本文奖从产业变…

【网络安全】零日漏洞(0day)是什么?如何防范零日攻击?

零日攻击是利用零日漏洞&#xff08;0day&#xff09;对系统或软件应用发动的网络攻击&#xff0c;近年来&#xff0c;零日攻击威胁在日益增长且难以防范&#xff0c;零日攻击已成为企业网络信息安全面临的最严峻的威胁之一。 文章目录 What is a zero-day attack&#xff1f;…

2023年12月8日历史上的今天大事件早读

1633年12月8日 明代科学家徐光启逝世 1794年12月8日 法国大革命吉伦派分子被接纳进法国国民大会 1813年12月8日 已丧失听觉的贝多芬指挥自己第七交响乐的首演音乐会 1856年12月8日 英国物理学家、电子发现者约瑟夫-约翰-汤姆逊出生 1920年12月8日 西北五马联合自治 1925年…

Python django-xadmin:构建强大的 Django 后台管理系统

概要 Django作为一款强大的Web框架&#xff0c;其后台管理系统提供了便捷的数据管理和操作方式。而 django-xadmin 则为Django的后台管理系统提供了更加强大的功能和灵活的定制选项。在本文中&#xff0c;我们将深入研究如何使用django-xadmin&#xff0c;并通过详细的示例代码…

0009Java程序设计-ssm微信小程序在慢性疾病管理中的应用

文章目录 **摘要**目录系统实现开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅&#x1f427;裙&#xff1a;776871563 摘要 首先,论文一开始便是清楚的论述了小程序的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例…