libhv是一个跨平台的C++网络库。
mysql是一个关系型数据库。
最好不要下载高版本的,容易出错!!!
下载地址MySQL
下载好后目录是这样的:
然后在环境变量里配置:
验证,打开cmd窗口,输入mysql --version
用的是visual studio,我下载的Mysql和libhv都是64位的,
模板:
#include "router.h"#include "handler.h"
#include "hv/hthread.h"
#include "hv/hasync.h" // import hv::async
#include "hv/requests.h" // import requests::asyncRouter::Router()
{}Router::~Router()
{}void Router::Register(hv::HttpService& router) {// preprocessor => Handler => postprocessorrouter.preprocessor = Handler::preprocessor;router.postprocessor = Handler::postprocessor;// router.errorHandler = Handler::errorHandler;// router.largeFileHandler = Handler::sendLargeFile;// router.POST("/dev", [](const HttpContextPtr& ctx) {
// // demo演示丢到hv::async全局线程池处理,实际使用推荐丢到自己的消费者线程/线程池
// hv::async([ctx]() {
// ctx->send(ctx->body(), ctx->type());
// });
// return 0;
// });// curl -v http://ip:port/login -H "Content-Type:application/json" -d '{"username":"admin","password":"123456"}'router.POST("/setValue", Handler::setValue);router.GET("/getValue", Handler::getValue);router.POST("/login", Handler::login);router.POST("/dev", Handler::DeviceManage);// curl -v http://ip:port/datarouter.GET("/data", [](HttpRequest* req, HttpResponse* resp) {static char data[] = "0123456789";return resp->Data(data, 10 /*, false */);});// curl -v http://ip:port/html/index.htmlrouter.GET("/html/index.html", [](HttpRequest* req, HttpResponse* resp) {return resp->File("html/index.html");});// curl -v http://ip:port/pathsrouter.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) {return resp->Json(router.Paths());});// curl -v http://ip:port/get?env=1router.GET("/get", [](HttpRequest* req, HttpResponse* resp) {resp->json["origin"] = req->client_addr.ip;resp->json["url"] = req->url;resp->json["args"] = req->query_params;resp->json["headers"] = req->headers;return 200;});// curl -v http://ip:port/servicerouter.GET("/service", [](const HttpContextPtr& ctx) {ctx->setContentType("application/json");ctx->set("base_url", ctx->service->base_url);ctx->set("document_root", ctx->service->document_root);ctx->set("home_page", ctx->service->home_page);ctx->set("error_page", ctx->service->error_page);ctx->set("index_of", ctx->service->index_of);return 200;});// curl -v http://ip:port/echo -d "hello,world!"router.POST("/echo", [](const HttpContextPtr& ctx) {return ctx->send(ctx->body(), ctx->type());});// wildcard *// curl -v http://ip:port/wildcard/anyrouter.GET("/wildcard*", [](HttpRequest* req, HttpResponse* resp) {std::string str = req->path + " match /wildcard*";return resp->String(str);});// curl -v http://ip:port/asyncrouter.GET("/async", [](const HttpRequestPtr& req, const HttpResponseWriterPtr& writer) {writer->Begin();writer->WriteHeader("X-Response-tid", hv_gettid());writer->WriteHeader("Content-Type", "text/plain");writer->WriteBody("This is an async response.\n");writer->End();});// curl -v http://ip:port/www.*// curl -v http://ip:port/www.example.comrouter.GET("/www.*", [](const HttpRequestPtr& req, const HttpResponseWriterPtr& writer) {HttpRequestPtr req2(new HttpRequest);req2->url = req->path.substr(1);requests::async(req2, [writer](const HttpResponsePtr& resp2){writer->Begin();if (resp2 == NULL) {writer->WriteStatus(HTTP_STATUS_NOT_FOUND);writer->WriteHeader("Content-Type", "text/html");writer->WriteBody("404 Not Found
");} else {writer->WriteResponse(resp2.get());}writer->End();});});// curl -v http://ip:port/sleep?t=1000router.GET("/sleep", Handler::sleep);// curl -v http://ip:port/setTimeout?t=1000router.GET("/setTimeout", Handler::setTimeout);// curl -v http://ip:port/query?page_no=1\&page_size=10router.GET("/query", Handler::query);// Content-Type: application/x-www-form-urlencoded// curl -v http://ip:port/kv -H "content-type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456'router.POST("/kv", Handler::kv);// Content-Type: application/json// curl -v http://ip:port/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}'router.POST("/json", Handler::json);// Content-Type: multipart/form-data// bin/curl -v http://ip:port/form -F 'user=admin' -F 'pswd=123456'router.POST("/form", Handler::form);// curl -v http://ip:port/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello'// curl -v http://ip:port/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}'// bin/curl -v http://ip:port/test -F 'bool=1' -F 'int=123' -F 'float=3.14' -F 'string=hello'router.POST("/test", Handler::test);// Content-Type: application/grpc// bin/curl -v --http2 http://ip:port/grpc -H "content-type:application/grpc" -d 'protobuf'router.POST("/grpc", Handler::grpc);// RESTful API: /group/:group_name/user/:user_id// curl -v -X DELETE http://ip:port/group/test/user/123router.Delete("/group/:group_name/user/:user_id", Handler::restful);// router.Delete("/group/{group_name}/user/{user_id}", Handler::restful);// curl -v http://ip:port/upload?filename=LICENSE -d '@LICENSE'// curl -v http://ip:port/upload -F 'file=@LICENSE'router.POST("/upload", Handler::upload);// curl -v http://ip:port/upload/README.md -d '@README.md'router.POST("/upload/{filename}", Handler::recvLargeFile);// SSE: Server Send Events// @test html/EventSource.html EventSource.onmessagerouter.GET("/sse", Handler::sse);
}
实践
/**
* 2022/11/4 与电脑客户端交互
*/int Handler::setValue(HttpRequest* req, HttpResponse* resp) {//拿到数据 存入数据库cout << req->body << endl;if (req->content_type != APPLICATION_JSON) {return response_status(resp, HTTP_STATUS_BAD_REQUEST);}resp->content_type = APPLICATION_JSON;hv::Json jsonData = req->GetJson();string jsonStr = jsonData.dump();cout << jsonStr << endl;Json::Value rValue;Json::Reader reader;if (!reader.parse(jsonStr.c_str(), rValue)) {resp->SetBody("0");return 0;}string SOC_IP = rValue["data"]["SOC_IP"].asString();string SOC_MAC = rValue["data"]["SOC_MAC"].asString();string NXP_IP = rValue["data"]["NXP_IP"].asString();string NXP_MAC = rValue["data"]["NXP_MAC"].asString();string NXP_VERSION = rValue["data"]["NXP_VERSION"].asString();string HISI_IP = rValue["data"]["HISI_IP"].asString();string HISI_MAC = rValue["data"]["HISI_MAC"].asString();string FPGA_VERSION = rValue["data"]["FPGA_VERSION"].asString();string HISI_VERSION = rValue["data"]["HISI_VERSION"].asString();string FACTORY_NAME = rValue["data"]["FACTORY_NAME"].asString();string BARCODE = rValue["data"]["BARCODE"].asString();string MANUFACTRING_DATE = rValue["data"]["MANUFACTRING_DATE"].asString();string ASSAMBLY_DATE = rValue["data"]["ASSAMBLY_DATE"].asString();deviceStruct deviceStruct;deviceStruct.SOC_IP = SOC_IP;deviceStruct.SOC_MAC = SOC_MAC;deviceStruct.NXP_IP = NXP_IP;deviceStruct.NXP_MAC = NXP_MAC;deviceStruct.NXP_VERSION = NXP_VERSION;deviceStruct.HISI_IP = HISI_IP;deviceStruct.HISI_MAC = HISI_MAC;deviceStruct.FPGA_VERSION = FPGA_VERSION;deviceStruct.HISI_VERSION = HISI_VERSION;deviceStruct.FACTORY_NAME = FACTORY_NAME;deviceStruct.BARCODE = BARCODE;deviceStruct.MANUFACTRING_DATE = MANUFACTRING_DATE;deviceStruct.ASSAMBLY_DATE = ASSAMBLY_DATE;if (mySqlObj.InsertData(deviceStruct, "deviceTable")) {resp->SetBody("1");}else{resp->SetBody("0");}return 200;}
/**
* 2022/11/4 与APP交互 与电脑端查询接口交互
*/int Handler::getValue(HttpRequest* req, HttpResponse* resp) {//取出传入的code值 遍历数据库找到返回json 未找到返回未找到std::map::const_iterator it = req->query_params.begin();req->query_params.size();for (; it != req->query_params.end(); it++){cout << "key=" << it->first << " value=" << it->second << endl;//查询到deviceStruct devStruct = {""};if (mySqlObj.QueryDatabase1(it->second, devStruct)){//组成json 发出去Json::Value rValue;rValue["SOC_IP"] = Json::Value(devStruct.SOC_IP);rValue["SOC_MAC"] = Json::Value(devStruct.SOC_MAC);rValue["NXP_IP"] = Json::Value(devStruct.NXP_IP);rValue["NXP_MAC"] = Json::Value(devStruct.NXP_MAC);rValue["NXP_VERSION"] = Json::Value(devStruct.NXP_VERSION);rValue["HISI_IP"] = Json::Value(devStruct.HISI_IP);rValue["HISI_MAC"] = Json::Value(devStruct.HISI_MAC);rValue["FPGA_VERSION"] = Json::Value(devStruct.FPGA_VERSION);rValue["HISI_VERSION"] = Json::Value(devStruct.HISI_VERSION);rValue["FACTORY_NAME"] = Json::Value(devStruct.FACTORY_NAME);rValue["BARCODE"] = Json::Value(devStruct.BARCODE);rValue["MANUFACTRING_DATE"] = Json::Value(devStruct.MANUFACTRING_DATE);rValue["ASSAMBLY_DATE"] = Json::Value(devStruct.ASSAMBLY_DATE);string str = Json::FastWriter().write(rValue);resp->SetBody(str);cout << str << endl;}else {//查询不到resp->SetBody("0");}}return 632222222;
}
数据库操作:
#include
#include //一定要包含这个
#include "define.h"#include
#include "mysqlSelf.h"
//包含附加依赖项,也可以在工程--属性里面设置
#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"libmysql.lib")CMySqlSelf::CMySqlSelf()
{init();
}CMySqlSelf::~CMySqlSelf()
{FreeConnect();
}void CMySqlSelf::init()
{ConnectDatabase();CreateTable();return;
}/**
* 创建表
*/
bool CMySqlSelf::CreateTable()
{int ret = 0;string strSql = "CREATE TABLE if not exists deviceTable(ID INT auto_increment primary key,SOC_IP VARCHAR(255), SOC_MAC VARCHAR(255), NXP_IP VARCHAR(255), NXP_MAC VARCHAR(255), NXP_VERSION VARCHAR(255), HISI_IP VARCHAR(255), HISI_MAC VARCHAR(255), FPGA_VERSION VARCHAR(255), HISI_VERSION VARCHAR(255),FACTORY_NAME VARCHAR(255),BARCODE VARCHAR(255),MANUFACTRING_DATE VARCHAR(255),ASSAMBLY_DATE VARCHAR(255));";if (mysql_query(&mysql, strSql.c_str())) {printf("Create failed (%s)", mysql_error(&mysql));return false;}else{printf("Create sucess");}
}/**
* 连接数据库
*/
bool CMySqlSelf::ConnectDatabase() {//初始化mysqlmysql_init(&mysql);mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "utf8");mysql_options(&mysql, MYSQL_INIT_COMMAND, "SET NAMES utf8");const char host[] = "127.0.0.1";const char user[] = "root";const char psw[] = "123456";const char table[] = "scantools";const int port = 3306;//返回false则连接失败,返回true则连接成功 if (!(mysql_real_connect(&mysql, host, user, psw, table, port, NULL, 0)))//中间分别是主机,用户名,密码,数据库名,端口号(可以写默认0或者3306等),可以先写成参数再传进去 {printf("Error connecting to database:%s", mysql_error(&mysql));return false;}else{printf("connect");return true;}
}/**
* 释放资源
*/
void CMySqlSelf::FreeConnect() {mysql_free_result(res); //释放一个结果集合使用的内存。mysql_close(&mysql); //关闭一个服务器连接。
}/*
* 转码
*/
string BitStrToStr(string bstr) {string str = "";//每八位转化成十进制,然后将数字结果转化成字符int sum;for (int i = 0; i < bstr.size(); i += 8){sum = 0;for (int j = 0; j < 8; j++)if (bstr[i + j] == '1')sum = sum * 2 + 1;elsesum = sum * 2;str = str + char(sum);}return str;}/**
* 插入
*/
bool CMySqlSelf::InsertData(deviceStruct info,string tableName) {char strSql[1024 * 1024] = { 0 };sprintf(strSql,"INSERT INTO devicetable(SOC_IP,SOC_MAC,NXP_IP,NXP_MAC,NXP_VERSION,HISI_IP,HISI_MAC,FPGA_VERSION,HISI_VERSION,FACTORY_NAME,BARCODE,MANUFACTRING_DATE,ASSAMBLY_DATE)VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')",info.SOC_IP.c_str(),info.SOC_MAC.c_str(),info.NXP_IP.c_str(),info.NXP_MAC.c_str(),info.NXP_VERSION.c_str(),info.HISI_IP.c_str(),info.HISI_MAC.c_str(),info.FPGA_VERSION.c_str(),info.HISI_VERSION.c_str(),info.FACTORY_NAME.c_str(),info.BARCODE.c_str(),info.MANUFACTRING_DATE.c_str(),info.ASSAMBLY_DATE.c_str());printf(strSql);if (mysql_query(&mysql, strSql)) {printf("m_query failed (%s)", mysql_error(&mysql));return false;}else{printf("Insert success");return true;}
}/**
* 查询
*/
string dbValue(MYSQL_ROW col, int index)
{if (col[index]){return col[index];}return "";
}bool CMySqlSelf::QueryDatabase1(string s, deviceStruct& devStruct) {memset(m_query, 0, 150);s = "select * from deviceTable where BARCODE = " + s;//s = "select * from deviceTable";memcpy(m_query, s.c_str(), sizeof(s));//写insert语句if (mysql_query(&mysql, m_query)){printf("Query failed (%s)", mysql_error(&mysql));return false;}else{printf("Query success");}//获取结果集 res = mysql_store_result(&mysql);if (!res) //获得sql语句结束后返回的结果集 {printf("Couldn't get result from %s", mysql_error(&mysql));return false;}int index = 1;while (column = mysql_fetch_row(res)) //在已知字段数量情况下,获取并打印下一行 {devStruct.SOC_IP = dbValue(column, index++);devStruct.SOC_MAC = dbValue(column, index++);devStruct.NXP_IP = dbValue(column, index++);devStruct.NXP_MAC = dbValue(column, index++);devStruct.NXP_VERSION = dbValue(column, index++);devStruct.HISI_IP = dbValue(column, index++);devStruct.HISI_MAC = dbValue(column, index++);devStruct.FPGA_VERSION = dbValue(column, index++);devStruct.HISI_VERSION = dbValue(column, index++);devStruct.FACTORY_NAME = dbValue(column, index++);devStruct.BARCODE = dbValue(column, index++);devStruct.MANUFACTRING_DATE = dbValue(column, index++);devStruct.ASSAMBLY_DATE = dbValue(column, index++);// printf("%10s %10s %10s %10s", column[0], column[1], column[2], column[3]); //column是列数组 }return true;
}
数据字段定义了一个结构体:
//结构体
struct deviceStruct
{string SOC_IP;string SOC_MAC;string NXP_IP;string NXP_MAC;string NXP_VERSION;string HISI_IP;string HISI_MAC;string FPGA_VERSION;string HISI_VERSION;string FACTORY_NAME;string BARCODE;string MANUFACTRING_DATE;string ASSAMBLY_DATE;
}
mysql可视化工具用的是navicat,数据库里的信息如下: