• C++ 结合mysql写一个服务端


    1 libhv和mysql

    libhv是一个跨平台的C++网络库。

    mysql是一个关系型数据库。

    2 下载MySQL,

    最好不要下载高版本的,容易出错!!!

    下载地址MySQL

    下载好后目录是这样的:

     然后在环境变量里配置:

    验证,打开cmd窗口,输入mysql --version

    3 C++里集成mysql和libhv

    用的是visual studio,我下载的Mysql和libhv都是64位的,

     

    模板:

    1. #include "router.h"
    2. #include "handler.h"
    3. #include "hv/hthread.h"
    4. #include "hv/hasync.h" // import hv::async
    5. #include "hv/requests.h" // import requests::async
    6. Router::Router()
    7. {
    8. }
    9. Router::~Router()
    10. {
    11. }
    12. void Router::Register(hv::HttpService& router) {
    13. // preprocessor => Handler => postprocessor
    14. router.preprocessor = Handler::preprocessor;
    15. router.postprocessor = Handler::postprocessor;
    16. // router.errorHandler = Handler::errorHandler;
    17. // router.largeFileHandler = Handler::sendLargeFile;
    18. // router.POST("/dev", [](const HttpContextPtr& ctx) {
    19. // // demo演示丢到hv::async全局线程池处理,实际使用推荐丢到自己的消费者线程/线程池
    20. // hv::async([ctx]() {
    21. // ctx->send(ctx->body(), ctx->type());
    22. // });
    23. // return 0;
    24. // });
    25. // curl -v http://ip:port/login -H "Content-Type:application/json" -d '{"username":"admin","password":"123456"}'
    26. router.POST("/setValue", Handler::setValue);
    27. router.GET("/getValue", Handler::getValue);
    28. router.POST("/login", Handler::login);
    29. router.POST("/dev", Handler::DeviceManage);
    30. // curl -v http://ip:port/data
    31. router.GET("/data", [](HttpRequest* req, HttpResponse* resp) {
    32. static char data[] = "0123456789";
    33. return resp->Data(data, 10 /*, false */);
    34. });
    35. // curl -v http://ip:port/html/index.html
    36. router.GET("/html/index.html", [](HttpRequest* req, HttpResponse* resp) {
    37. return resp->File("html/index.html");
    38. });
    39. // curl -v http://ip:port/paths
    40. router.GET("/paths", [&router](HttpRequest* req, HttpResponse* resp) {
    41. return resp->Json(router.Paths());
    42. });
    43. // curl -v http://ip:port/get?env=1
    44. router.GET("/get", [](HttpRequest* req, HttpResponse* resp) {
    45. resp->json["origin"] = req->client_addr.ip;
    46. resp->json["url"] = req->url;
    47. resp->json["args"] = req->query_params;
    48. resp->json["headers"] = req->headers;
    49. return 200;
    50. });
    51. // curl -v http://ip:port/service
    52. router.GET("/service", [](const HttpContextPtr& ctx) {
    53. ctx->setContentType("application/json");
    54. ctx->set("base_url", ctx->service->base_url);
    55. ctx->set("document_root", ctx->service->document_root);
    56. ctx->set("home_page", ctx->service->home_page);
    57. ctx->set("error_page", ctx->service->error_page);
    58. ctx->set("index_of", ctx->service->index_of);
    59. return 200;
    60. });
    61. // curl -v http://ip:port/echo -d "hello,world!"
    62. router.POST("/echo", [](const HttpContextPtr& ctx) {
    63. return ctx->send(ctx->body(), ctx->type());
    64. });
    65. // wildcard *
    66. // curl -v http://ip:port/wildcard/any
    67. router.GET("/wildcard*", [](HttpRequest* req, HttpResponse* resp) {
    68. std::string str = req->path + " match /wildcard*";
    69. return resp->String(str);
    70. });
    71. // curl -v http://ip:port/async
    72. router.GET("/async", [](const HttpRequestPtr& req, const HttpResponseWriterPtr& writer) {
    73. writer->Begin();
    74. writer->WriteHeader("X-Response-tid", hv_gettid());
    75. writer->WriteHeader("Content-Type", "text/plain");
    76. writer->WriteBody("This is an async response.\n");
    77. writer->End();
    78. });
    79. // curl -v http://ip:port/www.*
    80. // curl -v http://ip:port/www.example.com
    81. router.GET("/www.*", [](const HttpRequestPtr& req, const HttpResponseWriterPtr& writer) {
    82. HttpRequestPtr req2(new HttpRequest);
    83. req2->url = req->path.substr(1);
    84. requests::async(req2, [writer](const HttpResponsePtr& resp2){
    85. writer->Begin();
    86. if (resp2 == NULL) {
    87. writer->WriteStatus(HTTP_STATUS_NOT_FOUND);
    88. writer->WriteHeader("Content-Type", "text/html");
    89. writer->WriteBody("

      404 Not Found

      "
      );
    90. } else {
    91. writer->WriteResponse(resp2.get());
    92. }
    93. writer->End();
    94. });
    95. });
    96. // curl -v http://ip:port/sleep?t=1000
    97. router.GET("/sleep", Handler::sleep);
    98. // curl -v http://ip:port/setTimeout?t=1000
    99. router.GET("/setTimeout", Handler::setTimeout);
    100. // curl -v http://ip:port/query?page_no=1\&page_size=10
    101. router.GET("/query", Handler::query);
    102. // Content-Type: application/x-www-form-urlencoded
    103. // curl -v http://ip:port/kv -H "content-type:application/x-www-form-urlencoded" -d 'user=admin&pswd=123456'
    104. router.POST("/kv", Handler::kv);
    105. // Content-Type: application/json
    106. // curl -v http://ip:port/json -H "Content-Type:application/json" -d '{"user":"admin","pswd":"123456"}'
    107. router.POST("/json", Handler::json);
    108. // Content-Type: multipart/form-data
    109. // bin/curl -v http://ip:port/form -F 'user=admin' -F 'pswd=123456'
    110. router.POST("/form", Handler::form);
    111. // curl -v http://ip:port/test -H "Content-Type:application/x-www-form-urlencoded" -d 'bool=1&int=123&float=3.14&string=hello'
    112. // curl -v http://ip:port/test -H "Content-Type:application/json" -d '{"bool":true,"int":123,"float":3.14,"string":"hello"}'
    113. // bin/curl -v http://ip:port/test -F 'bool=1' -F 'int=123' -F 'float=3.14' -F 'string=hello'
    114. router.POST("/test", Handler::test);
    115. // Content-Type: application/grpc
    116. // bin/curl -v --http2 http://ip:port/grpc -H "content-type:application/grpc" -d 'protobuf'
    117. router.POST("/grpc", Handler::grpc);
    118. // RESTful API: /group/:group_name/user/:user_id
    119. // curl -v -X DELETE http://ip:port/group/test/user/123
    120. router.Delete("/group/:group_name/user/:user_id", Handler::restful);
    121. // router.Delete("/group/{group_name}/user/{user_id}", Handler::restful);
    122. // curl -v http://ip:port/upload?filename=LICENSE -d '@LICENSE'
    123. // curl -v http://ip:port/upload -F 'file=@LICENSE'
    124. router.POST("/upload", Handler::upload);
    125. // curl -v http://ip:port/upload/README.md -d '@README.md'
    126. router.POST("/upload/{filename}", Handler::recvLargeFile);
    127. // SSE: Server Send Events
    128. // @test html/EventSource.html EventSource.onmessage
    129. router.GET("/sse", Handler::sse);
    130. }

    实践

    1. /**
    2. * 2022/11/4 与电脑客户端交互
    3. */
    4. int Handler::setValue(HttpRequest* req, HttpResponse* resp) {
    5. //拿到数据 存入数据库
    6. cout << req->body << endl;
    7. if (req->content_type != APPLICATION_JSON) {
    8. return response_status(resp, HTTP_STATUS_BAD_REQUEST);
    9. }
    10. resp->content_type = APPLICATION_JSON;
    11. hv::Json jsonData = req->GetJson();
    12. string jsonStr = jsonData.dump();
    13. cout << jsonStr << endl;
    14. Json::Value rValue;
    15. Json::Reader reader;
    16. if (!reader.parse(jsonStr.c_str(), rValue)) {
    17. resp->SetBody("0");
    18. return 0;
    19. }
    20. string SOC_IP = rValue["data"]["SOC_IP"].asString();
    21. string SOC_MAC = rValue["data"]["SOC_MAC"].asString();
    22. string NXP_IP = rValue["data"]["NXP_IP"].asString();
    23. string NXP_MAC = rValue["data"]["NXP_MAC"].asString();
    24. string NXP_VERSION = rValue["data"]["NXP_VERSION"].asString();
    25. string HISI_IP = rValue["data"]["HISI_IP"].asString();
    26. string HISI_MAC = rValue["data"]["HISI_MAC"].asString();
    27. string FPGA_VERSION = rValue["data"]["FPGA_VERSION"].asString();
    28. string HISI_VERSION = rValue["data"]["HISI_VERSION"].asString();
    29. string FACTORY_NAME = rValue["data"]["FACTORY_NAME"].asString();
    30. string BARCODE = rValue["data"]["BARCODE"].asString();
    31. string MANUFACTRING_DATE = rValue["data"]["MANUFACTRING_DATE"].asString();
    32. string ASSAMBLY_DATE = rValue["data"]["ASSAMBLY_DATE"].asString();
    33. deviceStruct deviceStruct;
    34. deviceStruct.SOC_IP = SOC_IP;
    35. deviceStruct.SOC_MAC = SOC_MAC;
    36. deviceStruct.NXP_IP = NXP_IP;
    37. deviceStruct.NXP_MAC = NXP_MAC;
    38. deviceStruct.NXP_VERSION = NXP_VERSION;
    39. deviceStruct.HISI_IP = HISI_IP;
    40. deviceStruct.HISI_MAC = HISI_MAC;
    41. deviceStruct.FPGA_VERSION = FPGA_VERSION;
    42. deviceStruct.HISI_VERSION = HISI_VERSION;
    43. deviceStruct.FACTORY_NAME = FACTORY_NAME;
    44. deviceStruct.BARCODE = BARCODE;
    45. deviceStruct.MANUFACTRING_DATE = MANUFACTRING_DATE;
    46. deviceStruct.ASSAMBLY_DATE = ASSAMBLY_DATE;
    47. if (mySqlObj.InsertData(deviceStruct, "deviceTable")) {
    48. resp->SetBody("1");
    49. }
    50. else
    51. {
    52. resp->SetBody("0");
    53. }
    54. return 200;
    55. }
    1. /**
    2. * 2022/11/4 与APP交互 与电脑端查询接口交互
    3. */
    4. int Handler::getValue(HttpRequest* req, HttpResponse* resp) {
    5. //取出传入的code值 遍历数据库找到返回json 未找到返回未找到
    6. std::map::const_iterator it = req->query_params.begin();
    7. req->query_params.size();
    8. for (; it != req->query_params.end(); it++)
    9. {
    10. cout << "key=" << it->first << " value=" << it->second << endl;
    11. //查询到
    12. deviceStruct devStruct = {""};
    13. if (mySqlObj.QueryDatabase1(it->second, devStruct))
    14. {
    15. //组成json 发出去
    16. Json::Value rValue;
    17. rValue["SOC_IP"] = Json::Value(devStruct.SOC_IP);
    18. rValue["SOC_MAC"] = Json::Value(devStruct.SOC_MAC);
    19. rValue["NXP_IP"] = Json::Value(devStruct.NXP_IP);
    20. rValue["NXP_MAC"] = Json::Value(devStruct.NXP_MAC);
    21. rValue["NXP_VERSION"] = Json::Value(devStruct.NXP_VERSION);
    22. rValue["HISI_IP"] = Json::Value(devStruct.HISI_IP);
    23. rValue["HISI_MAC"] = Json::Value(devStruct.HISI_MAC);
    24. rValue["FPGA_VERSION"] = Json::Value(devStruct.FPGA_VERSION);
    25. rValue["HISI_VERSION"] = Json::Value(devStruct.HISI_VERSION);
    26. rValue["FACTORY_NAME"] = Json::Value(devStruct.FACTORY_NAME);
    27. rValue["BARCODE"] = Json::Value(devStruct.BARCODE);
    28. rValue["MANUFACTRING_DATE"] = Json::Value(devStruct.MANUFACTRING_DATE);
    29. rValue["ASSAMBLY_DATE"] = Json::Value(devStruct.ASSAMBLY_DATE);
    30. string str = Json::FastWriter().write(rValue);
    31. resp->SetBody(str);
    32. cout << str << endl;
    33. }
    34. else {
    35. //查询不到
    36. resp->SetBody("0");
    37. }
    38. }
    39. return 632222222;
    40. }

    数据库操作:

    1. #include
    2. #include //一定要包含这个
    3. #include "define.h"
    4. #include
    5. #include "mysqlSelf.h"
    6. //包含附加依赖项,也可以在工程--属性里面设置
    7. #pragma comment(lib,"wsock32.lib")
    8. #pragma comment(lib,"libmysql.lib")
    9. CMySqlSelf::CMySqlSelf()
    10. {
    11. init();
    12. }
    13. CMySqlSelf::~CMySqlSelf()
    14. {
    15. FreeConnect();
    16. }
    17. void CMySqlSelf::init()
    18. {
    19. ConnectDatabase();
    20. CreateTable();
    21. return;
    22. }
    23. /**
    24. * 创建表
    25. */
    26. bool CMySqlSelf::CreateTable()
    27. {
    28. int ret = 0;
    29. 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));";
    30. if (mysql_query(&mysql, strSql.c_str())) {
    31. printf("Create failed (%s)", mysql_error(&mysql));
    32. return false;
    33. }
    34. else
    35. {
    36. printf("Create sucess");
    37. }
    38. }
    39. /**
    40. * 连接数据库
    41. */
    42. bool CMySqlSelf::ConnectDatabase() {
    43. //初始化mysql
    44. mysql_init(&mysql);
    45. mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "utf8");
    46. mysql_options(&mysql, MYSQL_INIT_COMMAND, "SET NAMES utf8");
    47. const char host[] = "127.0.0.1";
    48. const char user[] = "root";
    49. const char psw[] = "123456";
    50. const char table[] = "scantools";
    51. const int port = 3306;
    52. //返回false则连接失败,返回true则连接成功
    53. if (!(mysql_real_connect(&mysql, host, user, psw, table, port, NULL, 0)))
    54. //中间分别是主机,用户名,密码,数据库名,端口号(可以写默认0或者3306等),可以先写成参数再传进去
    55. {
    56. printf("Error connecting to database:%s", mysql_error(&mysql));
    57. return false;
    58. }
    59. else
    60. {
    61. printf("connect");
    62. return true;
    63. }
    64. }
    65. /**
    66. * 释放资源
    67. */
    68. void CMySqlSelf::FreeConnect() {
    69. mysql_free_result(res); //释放一个结果集合使用的内存。
    70. mysql_close(&mysql); //关闭一个服务器连接。
    71. }
    72. /*
    73. * 转码
    74. */
    75. string BitStrToStr(string bstr) {
    76. string str = "";
    77. //每八位转化成十进制,然后将数字结果转化成字符
    78. int sum;
    79. for (int i = 0; i < bstr.size(); i += 8)
    80. {
    81. sum = 0;
    82. for (int j = 0; j < 8; j++)
    83. if (bstr[i + j] == '1')
    84. sum = sum * 2 + 1;
    85. else
    86. sum = sum * 2;
    87. str = str + char(sum);
    88. }
    89. return str;
    90. }
    91. /**
    92. * 插入
    93. */
    94. bool CMySqlSelf::InsertData(deviceStruct info,string tableName) {
    95. char strSql[1024 * 1024] = { 0 };
    96. sprintf(strSql,
    97. "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')",
    98. info.SOC_IP.c_str(),
    99. info.SOC_MAC.c_str(),
    100. info.NXP_IP.c_str(),
    101. info.NXP_MAC.c_str(),
    102. info.NXP_VERSION.c_str(),
    103. info.HISI_IP.c_str(),
    104. info.HISI_MAC.c_str(),
    105. info.FPGA_VERSION.c_str(),
    106. info.HISI_VERSION.c_str(),
    107. info.FACTORY_NAME.c_str(),
    108. info.BARCODE.c_str(),
    109. info.MANUFACTRING_DATE.c_str(),
    110. info.ASSAMBLY_DATE.c_str());
    111. printf(strSql);
    112. if (mysql_query(&mysql, strSql))
    113. {
    114. printf("m_query failed (%s)", mysql_error(&mysql));
    115. return false;
    116. }
    117. else
    118. {
    119. printf("Insert success");
    120. return true;
    121. }
    122. }
    123. /**
    124. * 查询
    125. */
    126. string dbValue(MYSQL_ROW col, int index)
    127. {
    128. if (col[index])
    129. {
    130. return col[index];
    131. }
    132. return "";
    133. }
    134. bool CMySqlSelf::QueryDatabase1(string s, deviceStruct& devStruct) {
    135. memset(m_query, 0, 150);
    136. s = "select * from deviceTable where BARCODE = " + s;
    137. //s = "select * from deviceTable";
    138. memcpy(m_query, s.c_str(), sizeof(s));//写insert语句
    139. if (mysql_query(&mysql, m_query)){
    140. printf("Query failed (%s)", mysql_error(&mysql));
    141. return false;
    142. }
    143. else
    144. {
    145. printf("Query success");
    146. }
    147. //获取结果集
    148. res = mysql_store_result(&mysql);
    149. if (!res) //获得sql语句结束后返回的结果集
    150. {
    151. printf("Couldn't get result from %s", mysql_error(&mysql));
    152. return false;
    153. }
    154. int index = 1;
    155. while (column = mysql_fetch_row(res)) //在已知字段数量情况下,获取并打印下一行
    156. {
    157. devStruct.SOC_IP = dbValue(column, index++);
    158. devStruct.SOC_MAC = dbValue(column, index++);
    159. devStruct.NXP_IP = dbValue(column, index++);
    160. devStruct.NXP_MAC = dbValue(column, index++);
    161. devStruct.NXP_VERSION = dbValue(column, index++);
    162. devStruct.HISI_IP = dbValue(column, index++);
    163. devStruct.HISI_MAC = dbValue(column, index++);
    164. devStruct.FPGA_VERSION = dbValue(column, index++);
    165. devStruct.HISI_VERSION = dbValue(column, index++);
    166. devStruct.FACTORY_NAME = dbValue(column, index++);
    167. devStruct.BARCODE = dbValue(column, index++);
    168. devStruct.MANUFACTRING_DATE = dbValue(column, index++);
    169. devStruct.ASSAMBLY_DATE = dbValue(column, index++);
    170. // printf("%10s %10s %10s %10s", column[0], column[1], column[2], column[3]); //column是列数组
    171. }
    172. return true;
    173. }

    数据字段定义了一个结构体:

    1. //结构体
    2. struct deviceStruct
    3. {
    4. string SOC_IP;
    5. string SOC_MAC;
    6. string NXP_IP;
    7. string NXP_MAC;
    8. string NXP_VERSION;
    9. string HISI_IP;
    10. string HISI_MAC;
    11. string FPGA_VERSION;
    12. string HISI_VERSION;
    13. string FACTORY_NAME;
    14. string BARCODE;
    15. string MANUFACTRING_DATE;
    16. string ASSAMBLY_DATE;
    17. }

    main函数中:

    1. Router::Register(g_http_service);
    2. g_http_server.setPort(8080, 0);
    3. g_http_server.registerHttpService(&g_http_service);
    4. http_server_run(&g_http_server);
    5. while (1)
    6. {
    7. Sleep(1);
    8. }
    9. return 0;

    mysql可视化工具用的是navicat,数据库里的信息如下:

  • 相关阅读:
    解决Docker启动之npm版本不兼容问题
    (六)admin-boot项目之全局处理预防xss攻击
    【嵌入式系统设计与实现】4 十字路口交通灯控制(简易版)
    关于C++中内存分区的知识
    人工智能和AR/VR:AI在AR和VR中扮演什么角色?行业应用有哪些?
    第二章 Caché 服务器页面简介 - 你应该知道
    深度学习之NLP
    kafka安装与相关配置详解
    Codeforces Round #802 (Div. 2)
    DetectX 深度学习模型Android部署 - NanoDetPlus + NCNN
  • 原文地址:https://blog.csdn.net/m0_56366502/article/details/127788990