TinywebServer代码详解– 配置文件(13)
原项目地址(点击跳转)
博主添加注释后项目地址(点击跳转)
一、基础知识
1.解析JSON文件
在本文中,使用JSON
文件存储,数据库服务器相关信息,有数据库服务器端口、数据库服务器用户名、密码、以及使用的数据库名
在程序运行时,调用函数对JSON
文件进行解析,获取数据。在本文中使用JSONCPP
库对JSON
文件进行解析
按照JSONCPP
库之后,出了源文件中包含JSONCPP
的头文件外#include <jsoncpp/json/json.h>
,在编译时,CMakeLists.txt
中也需要添加相关信息,使得程序可以正常编译,如下是一个使用JSONCPP
库的CMakeLists.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| cmake_minimum_required(VERSION 3.10) project(MyProject)
find_package(jsoncpp REQUIRED)
include_directories(${JSONCPP_INCLUDE_DIRS})
add_executable(app main.cpp)
target_link_libraries(app jsoncpp_lib)
|
使用JSON库解析JSON文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| bool Config::parseJsonFile() { std::ifstream ifs("/home/zxz/Proj/C_C++/WebServer/TinyWebServerBymyself/dbconf.json"); Json::Reader rd; Json::Value root; rd.parse(ifs,root); if(root.isObject()) { user = root["userName"].asString(); password = root["password"].asString(); databasename = root["dbName"].asString(); db_Port = root["db_port"].asInt(); return true; } return false; }
|
2.getopt函数
getopt()
函数是一个用于解析命令行选项的 C 语言标准库函数,它帮助程序处理命令行参数,使得用户可以输入格式化的选项和参数
1 2 3
| #include <unistd.h>
int getopt(int argc, char * const argv[], const char *optstring);
|
参数:
- argc: 命令行参数的数量
- argv: 命令行参数的数组
- optstring:一个字符串,包含程序可识别的选项字符(程序只接受短选项名,如
-h
),如果选项后跟冒号:
,则表示该选项后必须跟一个参数值
返回:
- 返回识别到的选项字符
- 如果所有命令行选项都已解析完毕,则返回 -1
- 如果遇到一个选项字符不在
optstring
中,则返回字符?
- 如果一个需要参数的选项未给出参数,则返回字符
:
(如果optstring
以冒号开始)
全局变量:
- optarg:指向当前选项参数(如果有)的指针。
- optind:下一个将被处理的元素的索引。
- opterr:如果不为零,
getopt()
会在遇到错误时打印错误信息
- optopt:它在某些特定情况下存储关于命令行选项的额外信息。当
getopt()
调用返回 ‘?’ 来表示一个错误——通常是因为遇到了一个未知选项或者一个需要参数的选项没有提供参数,optopt
变量会被设置为引起错误的选项字符
实例程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <stdio.h> #include <unistd.h>
int main(int argc, char *argv[]) { int opt; while ((opt = getopt(argc, argv, "abc:")) != -1) { switch (opt) { case 'a': printf("Option a is specified\n"); break; case 'b': printf("Option b is specified\n"); break; case 'c': printf("Option c is specified with value %s\n", optarg); break; case '?': printf("Unknown option: %c\n", optopt); break; default: printf("Other error\n"); } }
for (; optind < argc; optind++) { printf("Additional argument: %s\n", argv[optind]); }
return 0; }
|
二、代码解析
1.JSON文件
dbconf.json
1 2 3 4 5 6
| { "db_port": 3306, "userName": "zxz", "password": "123456", "dbName": "serverdb" }
|
2.config
config.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #pragma once #include "webserver.h"
class Config { public: Config(); ~Config(){};
void parse_arg(int argc, char*argv[]);
bool parseJsonFile();
int PORT;
int LOGWrite;
int TRIGMode;
int LISTENTrigmode;
int CONNTrigmode;
int OPT_LINGER;
int sql_num;
int thread_num;
int close_log;
int actor_model;
std::string user; std::string password; std::string databasename; int db_Port; };
|
config.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
| #include "config.h" #include <fstream> #include <jsoncpp/json/json.h>
Config::Config() { PORT = 9006;
LOGWrite = 0;
TRIGMode = 0;
LISTENTrigmode = 0;
CONNTrigmode = 0;
OPT_LINGER = 0;
sql_num = 8;
thread_num = 8;
close_log = 0;
actor_model = 0;
db_Port = 3306; }
bool Config::parseJsonFile() { std::ifstream ifs("/home/zxz/Proj/C_C++/WebServer/TinyWebServerBymyself/dbconf.json"); Json::Reader rd; Json::Value root; rd.parse(ifs,root); if(root.isObject()) { user = root["userName"].asString(); password = root["password"].asString(); databasename = root["dbName"].asString(); db_Port = root["db_port"].asInt(); return true; } return false; }
void Config::parse_arg(int argc, char*argv[]){ int opt; const char *str = "p:l:m:o:s:t:c:a:"; while ((opt = getopt(argc, argv, str)) != -1) { switch (opt) { case 'p': { PORT = atoi(optarg); break; } case 'l': { LOGWrite = atoi(optarg); break; } case 'm': { TRIGMode = atoi(optarg); break; } case 'o': { OPT_LINGER = atoi(optarg); break; } case 's': { sql_num = atoi(optarg); break; } case 't': { thread_num = atoi(optarg); break; } case 'c': { close_log = atoi(optarg); break; } case 'a': { actor_model = atoi(optarg); break; } default: break; } } }
|