#是注释行,
#每个有效配置项用 等号 处理,等号前不超过40个字符,等号后不超过400个字符;
#[开头的表示组信息,也等价于注释行
#[Socket]
#ListenPort = 5678
#DBInfo = 127.0.0.1;1234;myr;123456;mxdb_g
#日志相关
[Log]
#日志文件输出目录和文件名
#Log=logs/error.log
Log=error.log
#只打印日志等级<= 数字 的日志到日志文件中 ,日志等级0-8,0级别最高,8级别最低。
LogLevel = 8
#进程相关
[Proc]
#创建 这些个 worker进程
WorkerProcesses = 1
#是否按守护进程方式运行,1:按守护进程方式运行,0:不按守护进程方式运行
Daemon = 1
#处理接收到的消息的线程池中线程数量,不建议超过300
ProcMsgRecvWorkThreadCount = 120
#和网络相关
[Net]
#监听的端口数量,一般都是1个,当然如果支持多于一个也是可以的
ListenPortCount = 1
#ListenPort+数字【数字从0开始】,这种ListenPort开头的项有几个,取决于ListenPortCount的数量,
ListenPort0 = 80
#ListenPort1 = 443
#epoll连接的最大数【是每个worker进程允许连接的客户端数】,实际其中有一些连接要被监听socket使用,实际允许的客户端连接数会比这个数小一些
worker_connections = 2048
#Sock_RecyConnectionWaitTime:为确保系统稳定socket关闭后资源不会立即收回,而要等一定的秒数,在这个秒数之后,才进行资源/连接的回收
Sock_RecyConnectionWaitTime = 150
#Sock_WaitTimeEnable:是否开启踢人时钟,1:开启 0:不开启
Sock_WaitTimeEnable = 1
#多少秒检测一次是否 心跳超时,只有当Sock_WaitTimeEnable = 1时,本项才有用
Sock_MaxWaitTime = 20
#当时间到达Sock_MaxWaitTime指定的时间时,直接把客户端踢出去,只有当Sock_WaitTimeEnable = 1时,本项才有用
Sock_TimeOutKick = 0
#和网络安全相关
[NetSecurity]
#flood检测
#Flood攻击检测是否开启,1:开启 0:不开启
Sock_FloodAttackKickEnable = 1
#Sock_FloodTimeInterval表示每次收到数据包的时间间隔是100(单位:毫秒)
Sock_FloodTimeInterval = 100
#Sock_FloodKickCounter表示计算到连续10次,每次100毫秒时间间隔内发包,就算恶意入侵,把他kick出去
Sock_FloodKickCounter = 10
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <iostream>
#pragma warning(disable: 4996)
typedef struct _CConfItem
{
char ItemName[50];
char ItemContent[500];
}CConfItem, * LPCConfItem;
std::vector<LPCConfItem> m_ConfigItemList; //存储配置信息的列表
void Rtrim(char* string)
{
size_t len = 0;
if (string == NULL)
return;
len = strlen(string);
while (len > 0 && string[len - 1] == ' ') //位置换一下
string[--len] = 0;
return;
}
//截取字符串首部空格
void Ltrim(char* string)
{
size_t len = 0;
len = strlen(string);
char* p_tmp = string;
if ((*p_tmp) != ' ') //不是以空格开头
return;
//找第一个不为空格的
while ((*p_tmp) != '\0')
{
if ((*p_tmp) == ' ')
p_tmp++;
else
break;
}
if ((*p_tmp) == '\0') //全是空格
{
*string = '\0';
return;
}
char* p_tmp2 = string;
while ((*p_tmp) != '\0')
{
(*p_tmp2) = (*p_tmp);
p_tmp++;
p_tmp2++;
}
(*p_tmp2) = '\0';
return;
}
bool Load(const char* pconfName)
{
FILE* fp;
fp = fopen(pconfName, "r");
if (fp == NULL)
return false;
//每一行配置文件读出来都放这里
char linebuf[501]; //每行配置都不要太长,保持<500字符内,防止出现问题
//走到这里,文件打开成功
while (!feof(fp)) //检查文件是否结束 ,没有结束则条件成立
{
if (fgets(linebuf, 500, fp) == NULL) //从文件中读数据,每次读一行,一行最多不要超过500个字符
continue;
if (linebuf[0] == 0)
continue;
//处理注释行
if (*linebuf == ';' || *linebuf == ' ' || *linebuf == '#' || *linebuf == '\t' || *linebuf == '\n')
continue;
lblprocstring:
//屁股后边若有换行,回车,空格等都截取掉
if (strlen(linebuf) > 0)
{
if (linebuf[strlen(linebuf) - 1] == 10 || linebuf[strlen(linebuf) - 1] == 13 || linebuf[strlen(linebuf) - 1] == 32)
{
linebuf[strlen(linebuf) - 1] = 0;
goto lblprocstring;
}
}
if (linebuf[0] == 0)
continue;
if (*linebuf == '[') //[开头的也不处理
continue;
//这种 “ListenPort = 5678”走下来;
char* ptmp = strchr(linebuf, '=');
if (ptmp != NULL)
{
LPCConfItem p_confitem = new CConfItem; //注意前边类型带LP,后边new这里的类型不带
memset(p_confitem, 0, sizeof(CConfItem));
strncpy(p_confitem->ItemName, linebuf, (int)(ptmp - linebuf)); //等号左侧的拷贝到p_confitem->ItemName
strcpy(p_confitem->ItemContent, ptmp + 1); //等号右侧的拷贝到p_confitem->ItemContent
Rtrim(p_confitem->ItemName);
Ltrim(p_confitem->ItemName);
Rtrim(p_confitem->ItemContent);
Ltrim(p_confitem->ItemContent);
//printf("itemname=%s | itemcontent=%s\n",p_confitem->ItemName,p_confitem->ItemContent);
m_ConfigItemList.push_back(p_confitem); //内存要释放,因为这里是new出来的
} //end if
} //end while(!feof(fp))
fclose(fp); //这步不可忘记
return true;
}
int main()
{
Load("config.txt");
//for (std::vector<LPCConfItem>::iterator it = m_ConfigItemList.begin(); it!=m_ConfigItemList.end(); it++)
//{
// std::cout << (*it)->ItemName <<" "<< (*it)->ItemContent<<std::endl;
//}
for (auto i: m_ConfigItemList)
{
std::cout << i->ItemName << " " << i->ItemContent << std::endl;
}
return 0;
}
//使用
std::vector<LPCConfItem>::iterator pos;
for(pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
{
if(strcasecmp( (*pos)->ItemName,p_itemname) == 0)
return (*pos)->ItemContent;
}//end for
return NULL;