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
相关推荐
C++ 老炮儿的技术栈13 小时前
Qt Creator中不写代如何设置 QLabel的颜色
c语言·开发语言·c++·qt·算法
知无不研13 小时前
lambda表达式的原理和由来
java·开发语言·c++·lambda表达式
艾莉丝努力练剑13 小时前
【Linux:文件】基础IO
linux·运维·c语言·c++·人工智能·io·文件
小龙报13 小时前
【51单片机】深度解析 51 串口 UART:原理、配置、收发实现与工程化应用全总结
c语言·开发语言·c++·stm32·单片机·嵌入式硬件·51单片机
承渊政道13 小时前
C++学习之旅【C++中模板进阶内容介绍】
c语言·c++·笔记·学习·visual studio
浅念-13 小时前
C语言——动态内存管理
c语言·开发语言·c++·笔记·学习
Vect__16 小时前
基于线程池从零实现TCP计算器网络服务
c++·网络协议·tcp/ip
naruto_lnq21 小时前
分布式系统安全通信
开发语言·c++·算法
CSDN_RTKLIB1 天前
【四个场景测试】源文件编码UTF-8 BOM
c++