配置文件是服务器必不可少的主要模块之一,它记录着服务器的初始化的相关参数,例如服务器的端口和ip值,工作进程数目,工作根目录等,而在目前三大服务器(apache lighttpd nginx)的配置文件中会有更多更复杂的参数,使得服务器与该使用者的交互性大大的提高。
在之前的日记中所介绍的内存池的块大小和数目以及服务器的根目录的值是从配置文件上读取的。若大家需要移植该配置文件,只需要修改下面部分代码即可。现在我介绍一下配置文件的实现。
先看看存放配置文件信息的结构体实现:
typedef struct {
//服务器端口
int port;
//服务器主ip
char *bindip;
//服务器根目录
char *docroot;
//服务器工作目录
char *workdir;
//服务器日志文件
char *logfile;
//内存块的大小
size_t memblock_size;
//内存池的大小
size_t mempool_size;
//工作进程初始数目
int worker_num;
} server_config;
而读取配置文件信息的操作:
server_config *read_server_config()
{
FILE *fp = NULL;
char now_path[100], readline[100], key[100], value[100];
char *logfile_path = NULL;
size_t i, len, k_index = 0, v_index = 0, flag = 0;
server_config *temp = (server_config *) calloc(1,sizeof(server_config));
temp->bindip = calloc(100,sizeof(char));
temp->docroot = calloc(100,sizeof(char));
temp->workdir = calloc(100,sizeof(char));
temp->logfile = calloc(100,sizeof(char));
getcwd(now_path,100);
temp->workdir =memcpy(temp->workdir,now_path,strlen(now_path));
fp = fopen("test.conf","r");//配置文件所在的位置(根据实际情况修改)
if(fp == NULL)
{
printf("open configure file error!\n");
return NULL;
}
while((len = fread(readline,1,100,fp)) > 0)
{
for(i = 0; i < len;i ++)
{
if(readline[i] == '\t' || readline[i] == ' ' || (flag == 0 && readline[i] == '\n'))
{
continue;
}
else if(readline[i] == ':' || readline[i] == '=')
{
key[k_index] = '\0';
k_index = 0;
flag = 1;
}
else if(readline[i] == '\n')
{
value[v_index] = '\0';
if(strcmp("ip",key) == 0)
{
memcpy(temp->bindip,value,strlen(value));
}
else if(strcmp("port",key) == 0)
{
temp->port = atoi(value);
}
else if(strcmp("docroot",key) == 0)
{
memcpy(temp->docroot,now_path,strlen(now_path));
temp->docroot = strcat(temp->docroot,value);
}
else if(strcmp("logfile",key) == 0)
{
memcpy(temp->logfile,now_path,strlen(now_path));
temp->logfile = strcat(temp->logfile,value);
}
else if(strcmp("memblock_size",key) == 0)
{
temp->memblock_size = atoi(value);
}
else if(strcmp("mempool_size",key) == 0)
{
temp->mempool_size = atoi(value);
}
else if(strcmp("worker_num",key) == 0)
{
temp->worker_num = atoi(value);
}
else
{
printf("The configure file is error!\n");
server_config_free(temp);
fclose(fp);
return NULL;
}
v_index = 0;
flag = 0;
}
else if(flag)
{
value[v_index ++] = readline[i];
}
else
{
key[k_index ++] = readline[i];
}
}
}
if(flag)
{
value[v_index] = '\0';
if(strcmp("ip",key) == 0)
{
memcpy(temp->bindip,value,strlen(value));
}
else if(strcmp("port",key) == 0)
{
temp->port = atoi(value);
}
else if(strcmp("docroot",key) == 0)
{
memcpy(temp->docroot,now_path,strlen(now_path));
temp->docroot = strcat(temp->docroot,value);
}
else if(strcmp("logfile",key) == 0)
{
memcpy(temp->logfile,now_path,strlen(now_path));
temp->logfile = strcat(temp->logfile,value);
}
else if(strcmp("memblock_size",key) == 0)
{
temp->memblock_size = atoi(value);
}
else if(strcmp("mempool_size",key) == 0)
{
temp->mempool_size = atoi(value);
}
else if(strcmp("worker_num",key) == 0)
{
temp->worker_num = atoi(value);
}
else
{
printf("The configure file is error!\n");
server_config_free(temp);
fclose(fp);
return NULL;
}
}
if(!temp->port || !strlen(temp->bindip) || !strlen(temp->docroot) || !strlen(temp->workdir) || !strlen(temp->logfile))
{
server_config_free(temp);
fclose(fp);
return NULL;
}
return temp;
}
而配置文件(test.conf)的格式例子如下:
port:8086
ip:192.168.1.2
docroot:/www
logfile:/weblog/test.log
worker_num:5