python模組之os
阿新 • • 發佈:2022-12-05
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 }