C++实现JSON Web计算器

好的,这是一个使用C++实现的基于HTTP协议和JSON格式的简易Web计算器服务器方案。我们将使用Linux下的socket编程实现HTTP服务器,并解析客户端提交的JSON请求进行计算。


1. 项目架构概述

该服务器将实现以下功能:

  • HTTP请求处理:监听端口,解析GET/POST请求
  • JSON解析:处理客户端提交的数学表达式
  • 计算引擎:解析数学表达式并计算结果
  • JSON响应:将计算结果封装为JSON返回

2. 核心依赖

bash 复制代码
# 需要安装的库
sudo apt-get install libjsoncpp-dev  # JSON处理

3. 代码实现

3.1 HTTP服务器框架
cpp 复制代码
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <jsoncpp/json/json.h>

const int PORT = 8080;
const int BUFFER_SIZE = 1024;

int main() {
    // 创建socket
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in address = {
        .sin_family = AF_INET,
        .sin_addr.s_addr = INADDR_ANY,
        .sin_port = htons(PORT)
    };

    // 绑定端口
    bind(server_fd, (sockaddr*)&address, sizeof(address));
    listen(server_fd, 5);
    std::cout << "Server listening on port " << PORT << std::endl;

    while (true) {
        // 接受客户端连接
        sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);
        int client_socket = accept(server_fd, (sockaddr*)&client_addr, &client_len);

        // 读取HTTP请求
        char buffer[BUFFER_SIZE] = {0};
        read(client_socket, buffer, BUFFER_SIZE);

        // 处理请求(下一步实现)
        std::string response = handle_request(buffer);

        // 返回HTTP响应
        send(client_socket, response.c_str(), response.length(), 0);
        close(client_socket);
    }
    return 0;
}
3.2 JSON请求处理
cpp 复制代码
std::string handle_request(const char* request) {
    // 检测POST请求
    if (strstr(request, "POST /calculate") {
        // 提取JSON主体
        const char* json_start = strstr(request, "\r\n\r\n") + 4;
        Json::Value root;
        Json::Reader reader;
        
        if (reader.parse(json_start, root)) {
            std::string expr = root["expression"].asString();
            double result = calculate_expression(expr); // 计算模块
            
            // 构造JSON响应
            Json::Value resp;
            resp["result"] = result;
            return "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n" + resp.toStyledString();
        }
    }
    return "HTTP/1.1 400 Bad Request\r\n\r\nInvalid JSON";
}
3.3 数学表达式计算
cpp 复制代码
#include <cmath>
#include <stack>
#include <cctype>

double calculate_expression(const std::string& expr) {
    std::stack<double> values;
    std::stack<char> ops;
    
    for (int i = 0; i < expr.length(); i++) {
        if (expr[i] == ' ') continue;
        
        if (isdigit(expr[i])) {
            double val = 0;
            while (i < expr.length() && isdigit(expr[i])) {
                val = val * 10 + (expr[i] - '0');
                i++;
            }
            i--;
            values.push(val);
        }
        else if (expr[i] == '(') {
            ops.push(expr[i]);
        }
        else if (expr[i] == ')') {
            while (!ops.empty() && ops.top() != '(') {
                apply_op(values, ops);
            }
            ops.pop(); // 移除'('
        }
        else {
            // 处理运算符优先级
            while (!ops.empty() && precedence(ops.top()) >= precedence(expr[i])) {
                apply_op(values, ops);
            }
            ops.push(expr[i]);
        }
    }
    
    // 处理剩余操作
    while (!ops.empty()) {
        apply_op(values, ops);
    }
    return values.top();
}

// 辅助函数:应用运算符
void apply_op(std::stack<double>& values, std::stack<char>& ops) {
    double b = values.top(); values.pop();
    double a = values.top(); values.pop();
    char op = ops.top(); ops.pop();
    
    switch(op) {
        case '+': values.push(a + b); break;
        case '-': values.push(a - b); break;
        case '*': values.push(a * b); break;
        case '/': values.push(a / b); break;
        case '^': values.push(pow(a, b)); break;
    }
}

// 运算符优先级
int precedence(char op) {
    if (op == '^') return 3;
    if (op == '*' || op == '/') return 2;
    if (op == '+' || op == '-') return 1;
    return 0;
}

4. 客户端测试示例

使用curl发送请求:

bash 复制代码
curl -X POST http://localhost:8080/calculate \
     -H "Content-Type: application/json" \
     -d '{"expression": "2*(3+4)^2"}'

响应结果:

json 复制代码
{
  "result": 98
}

5. 安全与扩展建议

  1. 输入验证:添加正则表达式检查数学表达式合法性
  2. 错误处理:捕获除零错误等异常
  3. 多线程 :使用<thread>支持并发请求
  4. 函数扩展 :支持sin(x), log(x)等函数计算

此实现展示了从Socket通信到JSON解析的核心流程,可根据需求进一步扩展功能。注意编译时需链接JSON库:

bash 复制代码
g++ server.cpp -o server -ljsoncpp
相关推荐
favour_you___1 小时前
C++实现的高性能内存池项目
c++
ℳ๓₯㎕.空城旧梦1 小时前
C++中的解释器模式
开发语言·c++·算法
想七想八不如114081 小时前
面向对象程序设计--模拟题2查漏补缺
c++·考研
不想写代码的星星1 小时前
C++的'大自然搬运工':一文讲透using的所有用法
c++
2401_879503412 小时前
C++与FPGA协同设计
开发语言·c++·算法
今儿敲了吗2 小时前
46| FBI树
数据结构·c++·笔记·学习·算法
oem1102 小时前
C++中的访问者模式变体
开发语言·c++·算法
暮冬-  Gentle°3 小时前
C++中的工厂方法模式
开发语言·c++·算法
dfafadfadfafa4 小时前
嵌入式C++安全编码
开发语言·c++·算法
计算机安禾4 小时前
【C语言程序设计】第34篇:文件的概念与文件指针
c语言·开发语言·数据结构·c++·算法·visual studio code·visual studio