简单的客户端服务器(多线程)基于json通信

这是一个客户端和服务器通信的小项目,小编自己手写了一个json工具,测试比jsoncpp,protobuf "效率更高"(浅拷贝),改写成深拷贝效率会急剧下降(小编能力有限,知识点(多线程,json,c++11(万能模板,完美转发,包装器等),网络套接字)

改进:后序可以引进多线程,epoll模型(反应堆)或者引入负载均衡(并发数量大的情况),Json API更加完善。

Json/json.h

#pragma once
#include <string>
#include <vector>
#include <map>
#include <sstream>
#include <fstream>
#include <unordered_map>
using namespace std;

namespace yazi
{
    namespace json
    {
        class Json
        {
        public:
            typedef std::vector<Json>::iterator iterator;
            iterator begin()
            {
                return _vaule._array->begin();
            }
            iterator end()
            {
                return _vaule._array->end();
            }
            enum Type
            {
                json_null = 0,
                json_bool,
                json_int,
                json_double,
                json_string,
                json_array,
                json_object
            };
            Json();
            Json(bool vaule);
            Json(int vaule);
            Json(double vaule);
            Json(const char* vaule);
            Json(const std::string& vaule);
            Json(Type type);
            Json(const Json& other);

            operator bool();
            operator int();
            operator double();
            operator string();
            Json& operator[](int index);
            Json& operator[](const char* key);
            Json& operator[](const std::string& key);
            void operator=(const Json& other);
            bool operator==(const Json& other);
            bool operator!=(const Json& other);
            //Json& operator*();
            void append(const Json& other);
            size_t size() const;
            string str()const;
            void copy(const Json& other);
            void clear();
            bool isNull()const { return _type == json_null; }
            bool isBool()const { return _type == json_bool; }
            bool isInt()const { return _type == json_int; }
            bool isDouble()const { return _type == json_double; }
            bool isString()const { return _type == json_string; }
            bool isArray()const { return _type == json_array; }
            bool isObject()const { return _type == json_object; }

            bool asBool() const;
            int asInt()const;
            double asDouble()const;
            std::string asString()const;


            bool has(int index);
            bool has(const char* key);
            bool has(const std::string& key);


            void remove(int index);
            void remove(const char* key);
            void remove(const std::string& key);


            void parse(const std::string& str);
        private: 
            union Vaule
            {
                bool _bool;
                int _int;
                double _double;
                std::string* _string;
                std::vector<Json>* _array;
                std::map<std::string, Json>* _object;
            };
            Type _type;
            Vaule _vaule;
        };
    }
}

json/json.cc

#include "json.h"
#include "parser.h"
using namespace yazi::json;

Json::Json() : _type(json_null)
{
}
Json::Json(bool vaule) : _type(json_bool)
{
    _vaule._bool = vaule;
}
Json::Json(int vaule) : _type(json_int)
{
    _vaule._int = vaule;
}
Json::Json(double vaule) : _type(json_double)
{
    _vaule._double = vaule;
}
Json::Json(const char* vaule) : _type(json_string)
{
    _vaule._string = new std::string(vaule);
}
Json::Json(const std::string& vaule) : _type(json_string)
{
    _vaule._string = new std::string(vaule);
}
Json::Json(Type type) : _type(type)
{
    switch (_type)
    {
    case json_null:
        break;
    case json_bool:
        _vaule._bool = false;
        break;
    case json_int:
        _vaule._int = 0;
        break;
    case json_double:
        _vaule._double = 0.0;
        break;
    case json_string:
        _vaule._string = new std::string("");
        break;
    case json_array:
        _vaule._array = new std::vector<Json>();
        break;
    case json_object:
        _vaule._object = new std::map<std::string, Json>();
        break;
    default:
        break;
    }
}
Json::Json(const Json& other)
{
    copy(other);
}

Json::operator bool()
{
    if (_type != json_bool)
    {
        throw new logic_error("type error,not bool vaule");
    }
    return _vaule._bool;
}
Json::operator int()
{
    if (_type != json_int)
    {
        throw new logic_error("type error,not int vaule");
    }
    return _vaule._int;
}
Json::operator double()
{
    if (_type != json_double)
    {
        throw new logic_error("type error,not double vaule");
    }
    return _vaule._double;
}
Json::operator string()
{
    if (_type != json_string)
    {
        throw new logic_error("type error,not  string vaule");
    }
    return *(_vaule._string);
}

Json& Json::operator[](int index)
{
    if (_type != json_array)
    {
        clear();
        _type = json_array;
        _vaule._array = new std::vector<Json>();
    }
    // if(index < 0)
    // {
    //     throw new logic_error("array[] index < 0");
    // }
    size_t size = (_vaule._array)->size();
    if (index >= size) // 扩容
    {
        for (size_t i = size; i <= index; ++i)
        {
            (_vaule._array)->push_back(Json());
        }
    }
    return (_vaule._array)->at(index);
}
Json& Json::operator[](const char* key)
{
    std::string name(key);
    return (*(this))[name];
}
Json& Json::operator[](const std::string& key)
{
    if (_type != json_object)
    {
        clear();
        _type = json_object;
        _vaule._object = new std::map<std::string, Json>();
    }
    return (*(_vaule._object))[key];
}
void Json::operator=(const Json& other)
{
    clear();
    copy(other);
}
void Json::append(const Json& other)
{
    if (_type != json_array)
    {
        _type = json_array;
        _vaule._array = new std::vector<Json>();
    }
    (_vaule._array)->push_back(other);
}
size_t Json::size() const
{
    if (_type != json_array)
    {
        throw new logic_error("type error,not array vaule");
    }
    return (_vaule._array)->size();
}
string Json::str() const
{
    std::stringstream ss;
    switch (_type)
    {
    case json_null:
        ss << "null";
        break;
    case json_bool:
        if (_vaule._bool)
        {
            ss << "true";
        }
        else
        {
            ss << "false";
        }
        break;
    case json_int:
        ss << _vaule._int;
        break;
    case json_double:
        ss << _vaule._double;
        break;
    case json_string:
        ss << '\"' << *(_vaule._string) << '\"';
        break;
    case json_array:
    {
        ss << '[';
        for (auto it = (_vaule._array)->begin(); it != (_vaule._array)->end(); ++it)
        {
            if (it != (_vaule._array)->begin())
            {
                ss << ',';
            }
            ss << it->str();
        }
        ss << ']';
        break;
    }
    case json_object:
    {
        ss << '{';
        for (auto it = (_vaule._object)->begin(); it != (_vaule._object)->end(); ++it)
        {
            if (it != (_vaule._object)->begin())
            {
                ss << ',';
            }
            ss << '\"' << it->first << '\"' << ':' << it->second.str();
        }
        ss << '}';
        break;
    }
    default:
        break;
    }
    return ss.str();
}
void Json::copy(const Json& other)
{
    _type = other._type;
    switch (_type)
    {
    case json_null:
        break;
    case json_bool:
        _vaule._bool = other._vaule._bool;
        break;
    case json_int:
        _vaule._int = other._vaule._int;
        break;
    case json_double:
        _vaule._double = other._vaule._double;
        break;
    case json_string:
        _vaule._string = other._vaule._string;
        break;
    case json_array:
        _vaule._array = other._vaule._array;
        break;
    case json_object:
        _vaule._object = other._vaule._object;
        break;
    default:
        break;
    }
}
void Json::clear()
{
    switch (_type)
    {
    case json_null:
        break;
    case json_bool:
        _vaule._bool = false;
        break;
    case json_int:
        _vaule._int = 0;
        break;
    case json_double:
        _vaule._double = 0.0;
        break;
    case json_string:
        delete _vaule._string;
        break;
    case json_array:
    {
        for (auto it = _vaule._array->begin(); it != _vaule._array->end(); ++it)
        {
            it->clear();
        }
        delete _vaule._array;
        break;
    }
    case json_object:
    {
        for (auto it = _vaule._object->begin(); it != _vaule._object->end(); ++it)
        {
            (it->second).clear();
        }
        delete _vaule._object;
        break;
    }
    default:
        break;
    }
    _type = json_null;
}

bool Json::operator==(const Json& other) //浅拷贝(效率)
{
    if (_type != other._type)
    {
        return false;
    }
    switch (_type)
    {
    case json_null:
        return true;
    case json_bool:
        return _vaule._bool == other._vaule._bool;
    case json_int:
        return _vaule._int == other._vaule._int;
    case json_double:
        return _vaule._double == other._vaule._double;
    case json_string:
        return *(_vaule._string) == *(other._vaule._string);
    case json_array:
    {
       /*if(_vaule._array->size() != other._vaule._array->size())
       {
           return false;
       }
       for (size_t i = 0; i < _vaule._array->size(); ++i)
       {
           if ((*(_vaule._array))[i] != (* (other._vaule._array))[i])
           {
               return false;
           }
       }
       return true;*/
        return _vaule._array == other._vaule._array;
    }
    case json_object:
    {
        return _vaule._object == other._vaule._object;
    }
    default:
        break;
    }
    return false;
}
bool Json::operator!=(const Json& other)
{
    return !(*this == other);
}
bool Json::asBool() const
{
    if (_type != json_bool)
    {
        throw new std::logic_error("type error,not bool vaule");
    }
    return _vaule._bool;
}
int Json::asInt()const
{
    if (_type != json_int)
    {
        throw new std::logic_error("type error,not int vaule");
    }
    return _vaule._int;
}
double Json::asDouble()const
{
    if (_type != json_double)
    {
        throw new std::logic_error("type error,not double vaule");
    }
    return _vaule._double;
}
std::string Json::asString()const
{
    if (_type != json_string)
    {
        throw new std::logic_error("type error,not string vaule");
    }
    return *(_vaule._string);
}
bool Json::has(int index)
{
    if (_type != json_array)
    {
        return false;
    }
    int size = static_cast<int>((_vaule._array)->size());
    return (index >= 0 && index < size);
}
bool Json::has(const char* key)
{
    string name(key);
    return has(name);
}
bool Json::has(const std::string& key)
{
    if (_type != json_object)
    {
        return false;
    }
    return (_vaule._object)->find(key) != (_vaule._object)->end();
}

void Json::remove(int index)
{
    if (_type != json_array)
    {
        return;
    }
    int size = static_cast<int>((_vaule._array)->size());
    if (index < 0 || index >= size)
    {
        return;
    }
    (_vaule._array)->at(index).clear();
    (_vaule._array)->erase((_vaule._array)->begin() + index);
}
void Json::remove(const char* key)
{
    string name(key);
    return remove(name);
}
void Json::remove(const std::string& key)
{
    auto it = (_vaule._object)->find(key);
    if (it == (_vaule._object)->end())
    {
        return;
    }
    (*(_vaule._object))[key].clear();
    (_vaule._object)->erase(key);
}

void Json::parse(const std::string& str)
{
    Parser p;
    p.load(str);
    *this = p.parse();
}

json/parser.h

#pragma once
#include "json.h"
#include <string>
#include <regex>
namespace yazi
{
    namespace json
    {
        class Parser
        {
        public:
            Parser();
            void load(const std::string& str);
            Json parse();
        private:
            void skip_white_space();
            char get_next_token();
            Json parse_null();
            Json parse_bool();
            Json parse_number();
            std::string parse_string();
            Json parse_array();
            Json parse_object();
        private:
            std::string _str;
            int _index;
        };
    }
}

json.parser.cc

#include "parser.h"
using namespace yazi::json;
Parser::Parser() : _str(""), _index(0)
{
}
void Parser::load(const std::string& str)
{
    _str = str;
    _index = 0;
}
Json Parser::parse()
{
    char ch = get_next_token();
    switch (ch)
    {
    case 'n':
        --_index;
        return parse_null();
    case 't':
    case 'f':
        --_index;
        return parse_bool();
    case '-':
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
        --_index;
        return parse_number();
    case '"':
        return Json(parse_string());
    case '[':
        return parse_array();
    case '{':
        return parse_object();
    default:
        break;
    }
    throw new std::logic_error("unexpected char");
}
void Parser::skip_white_space()
{
    while (_str[_index] == ' ' || _str[_index] == '\n' || _str[_index] == '\r' || _str[_index] == '\t')
    {
        ++_index;
    }
}
char Parser::get_next_token()
{
    skip_white_space();
    return _str[_index++];
}
Json Parser::parse_null()
{
    if (_str.compare(_index, 4, "null") == 0)
    {
        _index += 4;
        return Json();
    }
    throw new std::logic_error("parse null error");
}
Json Parser::parse_bool()
{
    if (_str.compare(_index, 4, "true") == 0)
    {
        _index += 4;
        return Json(true);
    }
    else if (_str.compare(_index, 5, "false") == 0)
    {
        _index += 5;
        return Json(false);
    }
    else
    {
        throw new std::logic_error("parse bool error");
    }
}
Json Parser::parse_number()
{
    int pos = _index;
    if (_str[_index] == '-')
    {
        ++_index;
    }
    if (isdigit(_str[_index]) == 0)
    {
        throw new std::logic_error("parse number error");
    }
    while (isdigit(_str[_index]) != 0)
    {
        ++_index;
    }
    if (_str[_index] != '.')
    {
        int i = std::atoi(_str.c_str() + pos);
        return Json(std::move(i));
    }
    if (isdigit(_str[++_index]) == 0)
    {
        throw new std::logic_error("parse number error");
    }
    while (isdigit(_str[_index]) != 0)
    {
        ++_index;
    }
    double f = std::atof(_str.c_str() + pos);
    return Json(std::move(f));
}
std::string Parser::parse_string()
{
    std::string out;
    while (true)
    {
        char ch = _str[_index++];
        if (ch == '"')
        {
            break;
        }
        if (ch == '\\')
        {
            ch = _str[_index++];
            switch (ch)
            {
            case '\n':
                out += '\n';
                break;
            case '\r':
                out += '\r';
                break;
            case '\t':
                out += '\t';
                break;
            case '\b':
                out += '\b';
                break;
            case '\f':
                out += '\f';
                break;
            case '"':
                out += "\\\"";
                break;
            case '\\':
                out += "\\\\";
                break;
            case 'u':
                out += "\\u";
                for (int i = 0; i < 4; ++i)
                {
                    out += _str[_index++];
                }
                break;
            default:
                break;
            }
        }
        else
        {
            out += ch;
        }
    }
    return std::move(out);
}
Json Parser::parse_array()
{
    Json arr(Json::json_array);
    char ch = get_next_token();
    if (ch == ']')
    {
        return arr;
    }
    --_index;
    while (true)
    {
        arr.append(parse());   //递归解析
        ch = get_next_token();
        if (ch == ']')
        {
            break;
        }
        if (ch != ',')
        {
            throw new std::logic_error("parse array error");
        }
        //++_index;//ERROR
    }
    return arr;
}
Json Parser::parse_object()
{
    Json obj(Json::json_object);
    char ch = get_next_token();
    if(ch == '}')
    {
        return obj;
    }
    --_index;
    while(true)
    {
        ch = get_next_token();
        if(ch != '"')
        {
            throw new std::logic_error("parse object error");
        }
        std::string key = parse_string();
        ch = get_next_token();
        if(ch != ':')
        {
            throw new std::logic_error("parse object error");
        }
        obj[key] = parse();
        ch = get_next_token();
        if(ch == '}')
        {
            break;
        }
        if(ch != ',')
        {
            throw new std::logic_error("parse object error");
        }
        //++_index;//ERROR
    }
    return obj;
}

tcp_socket.hpp

#pragma once
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <cassert>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include "./json/json.h"
#include "./json/parser.h"
using namespace yazi::json;
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
#define CHECK_RET(exp) \
    if (!(exp))        \
    {                  \
        return false;  \
    }
class TcpSocket
{
public:
    TcpSocket() : fd_(-1) {}
    TcpSocket(int fd) : fd_(fd) {}
    bool Socket()
    {
        fd_ = socket(AF_INET, SOCK_STREAM, 0);
        if (fd_ < 0)
        {
            perror("socket");
            return false;
        }
        printf("open fd = %d\n", fd_);
        return true;
    }
    bool Close() const
    {
        close(fd_);
        printf("close fd = %d\n", fd_);
        return true;
    }
    bool Bind(const std::string &ip, uint16_t port) const
    {
        sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = inet_addr(ip.c_str());
        addr.sin_port = htons(port);
        int ret = bind(fd_, (sockaddr *)&addr, sizeof(addr));
        if (ret < 0)
        {
            perror("bind");
            return false;
        }
        return true;
    }
    bool Listen(int num) const
    {
        int ret = listen(fd_, num);
        if (ret < 0)
        {
            perror("listen");
            return false;
        }
        return true;
    }
    bool Accept(TcpSocket *peer, std::string *ip = NULL, uint16_t *port = NULL) const
    {
        sockaddr_in peer_addr;
        socklen_t len = sizeof(peer_addr);
        int new_sock = accept(fd_, (sockaddr *)&peer_addr, &len);
        if (new_sock < 0)
        {
            perror("accept");
            return false;
        }
        printf("accept fd = %d\n", new_sock);
        peer->fd_ = new_sock;
        if (ip != NULL)
        {
            *ip = inet_ntoa(peer_addr.sin_addr);
        }
        if (port != NULL)
        {
            *port = ntohs(peer_addr.sin_port);
        }
        return true;
    }
    bool Recv(std::string *buf) const
    {
        buf->clear();
        char tmp[1024 * 10] = {0};
        // [注意!] 这里的读并不算很严谨, 因为一次 recv 并不能保证把所有的数据都全部读完
        // 参考 man 手册 MSG_WAITALL 节.
        ssize_t read_size = recv(fd_, tmp, sizeof(tmp), 0);
        if (read_size < 0)
        {
            perror("recv");
            return false;
        }
        if (read_size == 0)
        {
            return false;
        }
        buf->assign(tmp, read_size);
        return true;
    }
    bool Recv(Json* result) const
    {
        result->clear();
        char tmp[1024 * 10] = {0};
        ssize_t read_size = recv(fd_, tmp, sizeof(tmp), 0);
        if (read_size < 0)
        {
            perror("recv");
            return false;
        }
        if (read_size == 0)
        {
            return false;
        }
        std::string name(tmp);
        (*result).parse(name);
        return true;
    }
    bool Send(const std::string &buf) const
    {
        ssize_t write_size = send(fd_, buf.data(), buf.size(), 0);
        if (write_size < 0)
        {
            perror("send");
            return false;
        }
        return true;
    }
    bool Send(const Json &vaule) const
    {
        ssize_t write_size = send(fd_, vaule.str().data(), vaule.str().size(), 0);
        if (write_size < 0)
        {
            perror("send");
            return false;
        }
        return true;
    }
    bool Connect(const std::string &ip, uint16_t port) const
    {
        sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = inet_addr(ip.c_str());
        addr.sin_port = htons(port);
        int ret = connect(fd_, (sockaddr *)&addr, sizeof(addr));
        if (ret < 0)
        {
            perror("connect");
            return false;
        }
        return true;
    }
    int GetFd() const
    {
        return fd_;
    }

private:
    int fd_;
};

tcp_client.hpp        

#pragma once
#include "tcp_socket.hpp"
class TcpClient
{
public:
    TcpClient(const std::string &ip, uint16_t port) : ip_(ip), port_(port)
    {
        // [注意!!] 需要先创建好 socket
        sock_.Socket();
    }
    ~TcpClient()
    {
        sock_.Close();
    }
    bool Connect()
    {
        return sock_.Connect(ip_, port_);
    }
    bool Recv(std::string *buf)
    {
        return sock_.Recv(buf);
    }
    bool Recv(Json* result)
    {
        return sock_.Recv(result);
    }
    bool Send(const std::string &buf)
    {
        return sock_.Send(buf);
    }
    bool Send(const Json& vaule)
    {
        return sock_.Send(vaule);
    }
private:
    TcpSocket sock_;
    std::string ip_;
    uint16_t port_;
};

tcp_server.hpp

#pragma once
#include <functional>
#include <pthread.h>
#include "tcp_socket.hpp"
typedef std::function<void(const std::string &, std::string *)> Handler;
struct ThreadArg
{
    TcpSocket new_sock;
    std::string ip;
    uint16_t port;
    Handler handler;
};
class TcpThreadServer
{
public:
    TcpThreadServer(const std::string &ip, uint16_t port) : ip_(ip), port_(port)
    {
    }
    bool Start(Handler handler)
    {
        // 1. 创建 socket;
        CHECK_RET(listen_sock_.Socket());
        // 2. 绑定端口号
        CHECK_RET(listen_sock_.Bind(ip_, port_));
        // 3. 进行监听
        CHECK_RET(listen_sock_.Listen(5));
        // 4. 进入循环
        for (;;)
        {
            // 5. 进行 accept
            ThreadArg *arg = new ThreadArg();
            arg->handler = handler;
            bool ret = listen_sock_.Accept(&arg->new_sock, &arg->ip, &arg->port);
            if (!ret)
            {
                continue;
            }
            printf("[client %s:%d] connect\n", arg->ip.c_str(), arg->port);
            // 6. 创建新的线程完成具体操作
            pthread_t tid;
            pthread_create(&tid, NULL, ThreadEntry, arg);
            pthread_detach(tid);
        }
        return true;
    }
    // 这里的成员函数为啥非得是 static?
    static void *ThreadEntry(void *arg)
    {
        // C++ 的四种类型转换都是什么?
        ThreadArg *p = reinterpret_cast<ThreadArg *>(arg);
        ProcessConnect(p);
        // 一定要记得释放内存!!! 也要记得关闭文件描述符
        p->new_sock.Close();
        delete p;
        return NULL;
    }
    // 处理单次连接. 这个函数也得是 static
    static void ProcessConnect(ThreadArg *arg)
    {
        // 1. 循环进行读写
        for (;;)
        {
            std::string req;
            // 2. 读取请求
            bool ret = arg->new_sock.Recv(&req);
            if (!ret)
            {
                printf("[client %s:%d] disconnected!\n", arg->ip.c_str(), arg->port);
                break;
            }
            std::string resp;
            // 3. 根据请求计算响应
            arg->handler(req, &resp);
            // 4. 发送响应
            arg->new_sock.Send(resp);
            printf("[client %s:%d] req: %s, resp: %s\n", arg->ip.c_str(),
                   arg->port, req.c_str(), resp.c_str());
        }
    }

private:
    TcpSocket listen_sock_;
    std::string ip_;
    uint16_t port_;
};

 dict_client.cc

#include "tcp_client.hpp"
#include <iostream>
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        printf("Usage ./dict_client [ip] [port]\n");
        return 1;
    }
    TcpClient client(argv[1], atoi(argv[2]));
    bool ret = client.Connect();
    if (!ret)
    {
        return 1;
    }
    // for (;;)
    // {
    //     std::cout << "请输入要查询的单词:" << std::endl;
    //     std::string word;
    //     std::cin >> word;
    //     if (!std::cin)
    //     {
    //         break;
    //     }
    //     client.Send(word);
    //     std::string result;
    //     client.Recv(&result);
    //     std::cout << result << std::endl;
    // }
    for (;;)  //客户端创建json串发往服务器
    {
        std::cout << "请输入你的协议:" << std::endl;
        // const std::string& str = "{\"a\":true,\"b\":{\"a\":true,\"b\":[1, \"a\", 3, null, -1.2345, true, false, \"hello world\"],\"c\":123,\"4\":\"hello world\"},\"c\":123,\"4\":\"hello world\"}";
        // Json v;
        // v.parse(str);
        // std::cout << v.str() << std::endl;
        // client.Send(v.str());
        Json arr;
        arr[1] = true;
        arr[2] = 123;
        arr[3] = 1.23;
        arr[4] = "hello";
        Json obj;
        obj["bool"] = true;
        obj["int"] = 123;
        obj["double"] = 1.23;
        obj["arr"] = arr;
        std::cout << obj.str() << std::endl;
        client.Send(obj);
        obj.clear();

        Json result;
        // client.Recv(result);
        // std::string result;
        client.Recv(&result);
        std::cout << result.str() << std::endl;
    }
    return 0;
}

dict_server.cc

#include <unordered_map>
#include "tcp_server.hpp"
#include "./json/json.h"
#include "./json/parser.h"
std::unordered_map<std::string, std::string> g_dict;
// void Translate(const std::string &req, std::string *resp)
// {
//     auto it = g_dict.find(req);
//     if (it == g_dict.end())
//     {
//         *resp = "未找到";
//         return;
//     }
//     *resp = it->second;
//     return;
// }
void Translate(const std::string &req, std::string *resp)
{
    // auto it = g_dict.find(req);
    // if (it == g_dict.end())
    // {
    //     *resp = "未找到";
    //     return;
    // }
    // *resp = it->second;
    // return;

    Json vaule;
    vaule.parse(req);
    if(vaule["bool"])
    {
        Json obj;
        //收到Json串这里可以有服务器自己处理业务
        //obj["服务器"] = "收到了";
        Json arr;
        arr[0] = "服务器收到客户端的数据了";
        arr[1] = "服务器发往客户端的协议为:932";
        arr[2] = 932;
        obj["服务器"] = arr;
        *resp = obj.str();
        obj.clear();
    }
    vaule.clear();
}
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        printf("Usage ./dict_server [ip] [port]\n");
        return 1;
    }
    // 1. 初始化词典
    //g_dict.insert(std::make_pair("hello", "你好"));
    //g_dict.insert(std::make_pair("world", "世界"));
    //g_dict.insert(std::make_pair("bit", "贼NB"));
    // 2. 启动服务器
    TcpThreadServer server(argv[1], atoi(argv[2]));
    server.Start(Translate);
    return 0;
}

makefile

.PHONY:all
all:dict_client dict_server
dict_client:dict_client.cc ./json/json.cc ./json/parser.cc
dict_client.cc:
	g++ -o $@  $^ -std=c++11
dict_server:dict_server.cc ./json/json.cc ./json/parser.cc
	g++ -o $@ $^  -std=c++11 -lpthread
.PHONY:clean
clean:
	rm -rf dict_client dict_server

测试截图:

 

 

githup地址: 

 基于Josn的网络通信

josn工具

protobuf工具

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值