1. 配置文件(nginx.conf)
1 #是注释行, 2 #每个有效配置项用 等号 处理,等号前不超过40个字符,等号后不超过400个字符; 3 4 5 #[开头的表示组信息,也等价于注释行 6 #[Socket] 7 #ListenPort = 5678 8 #DBInfo = 127.0.0.1;1234;myr;123456;mxdb_g 9 10 #日志相关 11 [Log] 12 #日志文件输出目录和文件名 13 #Log=logs/error.log 14 Log=error.log 15 16 #只打印日志等级<= 数字 的日志到日志文件中 ,日志等级0-8,0级别最高,8级别最低。 17 LogLevel = 8 18 19 #进程相关 20 [Proc] 21 #创建 这些个 worker进程 22 WorkerProcesses = 4 23 24 #是否按守护进程方式运行,1:按守护进程方式运行,0:不按守护进程方式运行 25 Daemon = 1 26 27 #处理接收到的消息的线程池中线程数量,不建议超过300 28 ProcMsgRecvWorkThreadCount = 120 29 30 #和网络相关 31 [Net] 32 #监听的端口数量,一般都是1个,当然如果支持多于一个也是可以的 33 ListenPortCount = 1 34 #ListenPort+数字【数字从0开始】,这种ListenPort开头的项有几个,取决于ListenPortCount的数量, 35 ListenPort0 = 80 36 #ListenPort1 = 443 37 38 #epoll连接的最大数【是每个worker进程允许连接的客户端数】,实际其中有一些连接要被监听socket使用,实际允许的客户端连接数会比这个数小一些 39 worker_connections = 2048 40 41 #Sock_RecyConnectionWaitTime:为确保系统稳定socket关闭后资源不会立即收回,而要等一定的秒数,在这个秒数之后,才进行资源/连接的回收 42 Sock_RecyConnectionWaitTime = 150 43 44 #Sock_WaitTimeEnable:是否开启踢人时钟,1:开启 0:不开启 45 Sock_WaitTimeEnable = 1 46 #多少秒检测一次是否 心跳超时,只有当Sock_WaitTimeEnable = 1时,本项才有用 47 Sock_MaxWaitTime = 20 48 #当时间到达Sock_MaxWaitTime指定的时间时,直接把客户端踢出去,只有当Sock_WaitTimeEnable = 1时,本项才有用 49 Sock_TimeOutKick = 0 50 51 #和网络安全相关 52 [NetSecurity] 53 #flood检测 54 #Flood攻击检测是否开启,1:开启 0:不开启 55 Sock_FloodAttackKickEnable = 1 56 #Sock_FloodTimeInterval表示每次收到数据包的时间间隔是100(单位:毫秒) 57 Sock_FloodTimeInterval = 100 58 #Sock_FloodKickCounter表示计算到连续10次,每次100毫秒时间间隔内发包,就算恶意入侵,把他kick出去 59 Sock_FloodKickCounter = 10
2. 头文件(ngx_c_conf.h)
1 #ifndef NGX_C_CONF_H 2 #define NGX_C_CONF_H 3 #include <vector> 4 #include <stdio.h> 5 #include <string.h> 6 //结构定义 7 typedef struct _CConfItem 8 { 9 char ItemName[50]; 10 char ItemContent[500]; 11 }CConfItem,*LPCConfItem; 12 13 14 //类名可以遵照一定的命名规则规范,比如老师这里,第一个字母是C,后续的单词首字母大写 15 class CConfig 16 { 17 //--------------------------------------------------- 18 //这段代码老师在《c++从入门到精通》 多线程这章老师提过 单例设计模式,就是如下这些代码,大家即便没学过,也可以现在学 19 private: 20 CConfig(); 21 public: 22 ~CConfig(); 23 private: 24 static CConfig *m_instance; 25 26 public: 27 static CConfig* GetInstance() //采用的是单例模式中的饿汉式 28 { 29 if(m_instance == nullptr) 30 { 31 //锁 32 if(m_instance == nullptr) 33 { 34 m_instance = new CConfig(); 35 static CGarhuishou cl; 36 } 37 //放锁 38 } 39 return m_instance; 40 } 41 class CGarhuishou //类中套类,用于释放对象 42 { 43 public: 44 ~CGarhuishou() 45 { 46 if (CConfig::m_instance) 47 { 48 delete CConfig::m_instance; 49 CConfig::m_instance = nullptr; 50 } 51 } 52 }; 53 //--------------------------------------------------- 54 public: 55 bool Load(const char *pconfName); //装载配置文件 56 const char *GetString(const char *p_itemname); 57 int GetIntDefault(const char *p_itemname,const int def); 58 59 public: 60 std::vector<LPCConfItem> m_ConfigItemList; //存储配置信息的列表 61 }; 62 63 #endif // NGX_C_CONF_H
3. 源文件(ngx_c_conf.cpp)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <vector> 5 6 //自定义头文件放下边,因为g++中用了-I参数,所以这里用<>也可以 7 #include "ngx_c_conf.h" //和配置文件处理相关的类,名字带c_表示和类有关 8 9 //截取字符串尾部空格 10 void Rtrim(char *string) 11 { 12 size_t len = 0; 13 if(string == NULL) 14 return; 15 16 len = strlen(string); 17 while(len > 0 && string[len-1] == ' ') //位置换一下 18 string[--len] = 0; 19 return; 20 } 21 22 //截取字符串首部空格 23 void Ltrim(char *string) 24 { 25 size_t len = 0; 26 len = strlen(string); 27 char *p_tmp = string; 28 if( (*p_tmp) != ' ') //不是以空格开头 29 return; 30 //找第一个不为空格的 31 while((*p_tmp) != '\0') 32 { 33 if( (*p_tmp) == ' ') 34 p_tmp++; 35 else 36 break; 37 } 38 if((*p_tmp) == '\0') //全是空格 39 { 40 *string = '\0'; 41 return; 42 } 43 char *p_tmp2 = string; 44 while((*p_tmp) != '\0') 45 { 46 (*p_tmp2) = (*p_tmp); 47 p_tmp++; 48 p_tmp2++; 49 } 50 (*p_tmp2) = '\0'; 51 return; 52 } 53 54 55 56 //静态成员赋值 57 CConfig *CConfig::m_instance = NULL; 58 59 //构造函数 60 CConfig::CConfig() 61 { 62 } 63 64 //析构函数 65 CConfig::~CConfig() 66 { 67 std::vector<LPCConfItem>::iterator pos; 68 for(pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos) 69 { 70 delete (*pos); 71 }//end for 72 m_ConfigItemList.clear(); 73 return; 74 } 75 76 //装载配置文件 77 bool CConfig::Load(const char *pconfName) 78 { 79 FILE *fp; 80 fp = fopen(pconfName,"r"); 81 if(fp == NULL) 82 return false; 83 84 //每一行配置文件读出来都放这里 85 char linebuf[501]; //每行配置都不要太长,保持<500字符内,防止出现问题 86 87 //走到这里,文件打开成功 88 while(!feof(fp)) //检查文件是否结束 ,没有结束则条件成立 89 { 90 //大家要注意老师的写法,注意写法的严密性,商业代码,就是要首先确保代码的严密性 91 if(fgets(linebuf,500,fp) == NULL) //从文件中读数据,每次读一行,一行最多不要超过500个字符 92 continue; 93 94 if(linebuf[0] == 0) 95 continue; 96 97 //处理注释行 98 if(*linebuf==';' || *linebuf==' ' || *linebuf=='#' || *linebuf=='\t'|| *linebuf=='\n') 99 continue; 100 101 lblprocstring: 102 //屁股后边若有换行,回车,空格等都截取掉 103 if(strlen(linebuf) > 0) //strlen不算\0 104 { //看看末尾的字符是什么 10代表换行符,13代表回车键,32代表空格 105 if(linebuf[strlen(linebuf)-1] == 10 || linebuf[strlen(linebuf)-1] == 13 || linebuf[strlen(linebuf)-1] == 32) 106 { 107 linebuf[strlen(linebuf)-1] = 0; 108 goto lblprocstring; 109 } 110 } 111 112 if(linebuf[0] == 0) 113 continue; 114 if(*linebuf=='[') //[开头的也不处理 115 continue; 116 117 //这种 “ListenPort = 5678”走下来; 118 char *ptmp = strchr(linebuf,'='); //strchr搜索第一次出现字符=的位置 119 if(ptmp != NULL) 120 { 121 LPCConfItem p_confitem = new CConfItem; //注意前边类型带LP,后边new这里的类型不带 122 memset(p_confitem,0,sizeof(CConfItem)); 123 strncpy(p_confitem->ItemName,linebuf,(int)(ptmp-linebuf)); //等号左侧的拷贝到p_confitem->ItemName 124 strcpy(p_confitem->ItemContent,ptmp+1); //等号右侧的拷贝到p_confitem->ItemContent 125 126 Rtrim(p_confitem->ItemName); 127 Ltrim(p_confitem->ItemName); 128 Rtrim(p_confitem->ItemContent); 129 Ltrim(p_confitem->ItemContent); 130 131 //printf("itemname=%s | itemcontent=%s\n",p_confitem->ItemName,p_confitem->ItemContent); 132 m_ConfigItemList.push_back(p_confitem); //内存要释放,因为这里是new出来的 133 } //end if 134 } //end while(!feof(fp)) 135 136 fclose(fp); //这步不可忘记 137 return true; 138 } 139 140 //根据ItemName获取配置信息字符串,不修改不用互斥 141 const char *CConfig::GetString(const char *p_itemname) 142 { 143 std::vector<LPCConfItem>::iterator pos; 144 for(pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos) 145 { 146 if(strcasecmp( (*pos)->ItemName,p_itemname) == 0) 147 return (*pos)->ItemContent; 148 }//end for 149 return NULL; 150 } 151 152 //根据ItemName获取数字类型配置信息,不修改不用互斥 153 int CConfig::GetIntDefault(const char *p_itemname,const int def) 154 { 155 std::vector<LPCConfItem>::iterator pos; 156 for(pos = m_ConfigItemList.begin(); pos !=m_ConfigItemList.end(); ++pos) 157 { 158 if(strcasecmp( (*pos)->ItemName,p_itemname) == 0) 159 return atoi((*pos)->ItemContent); 160 }//end for 161 return def; 162 }
4. main函数(用来测试)
1 #include <stdio.h> 2 #include <ngx_c_conf.h> 3 4 int main() 5 { 6 7 CConfig *p_config = CConfig::GetInstance(); //单例类 8 9 if(p_config->Load("C:\\Users\\123\\Documents\\build-test-Desktop_Qt_5_9_9_MinGW_32bit-Debug\\debug\\nginx.conf") == false) //把配置文件内容载入到内存 10 { 11 printf("Load configFile failed\n"); 12 } 13 else 14 { //只是简单的测试了一下,如果获取数字型的配置信息可以用这个GetIntDefault(const char *p_itemname,const int def)函数,直接得到数字
15 printf("Load configFile success\n"); 16 printf("log = %s\n",p_config->GetString("Log")); 17 printf("LogLevel = %s\n",p_config->GetString("LogLevel")); 18 printf("WorkerProcesses = %s\n",p_config->GetString("WorkerProcesses")); 19 printf("Daemon = %s\n",p_config->GetString("Daemon")); 20 } 21 return 0; 22 }标签:return,读取,配置文件,pos,CConfig,char,linebuf,confitem From: https://www.cnblogs.com/dkhlaojogo/p/16972116.html