好的,这是一个使用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. 安全与扩展建议
- 输入验证:添加正则表达式检查数学表达式合法性
- 错误处理:捕获除零错误等异常
- 多线程 :使用
<thread>支持并发请求 - 函数扩展 :支持
sin(x),log(x)等函数计算
此实现展示了从Socket通信到JSON解析的核心流程,可根据需求进一步扩展功能。注意编译时需链接JSON库:
bash
g++ server.cpp -o server -ljsoncpp