linux下php安装sockt,Linux下Socket编程(五)——http容器(支持php)

简介

理解http报文格式

socket+epoll+多线程框架

请求和响应类封装

正则表达式解析头部

请求文件读取

php-cgi解析php文件

理解http报文格式

socket+epoll+多线程框架

请求和响应类封装

为了方便操作以及功能模块的拆分,这里我们将请求内容和响应内容进行封装。这里我们只列出头文件,封装类中我们仅仅做了关系字段的提取。

Request.h

请求报文进行封装,我们将请求的内容放到body中,然后调用parse进行解析,解析后的数据分别存放到定义的成员变量中。

#ifndef REQUEST_H

#define REQUEST_H

#include

using namespace std;

#include

#include

class Request{

private:

string body;

string method;

string path;

string protocol;

string content;

string postfix;

map headers;

map params;

public:

Request();

~Request();

void setBody(string body);

bool parse();

string getMethod();

string getPath();

string getProtocol();

string getContent();

string getPostfix();

map getParam();

map getHeaders();

};

#endif

Reponse.h

对响应报文进行封装,重要是响应状态吗、协议、Content-Length等。通过getData对头部进行拼装。

#ifndef RESPONSE_H

#define RESPONSE_H

#include

using namespace std;

#include

#include

class Response{

private:

int code;

string msg;

string protocol;

map headers;

public:

Response();

~Response();

void setCode(int code);

void setMsg(const char* msg);

void setProtocol(const char protocol);

void addHead(string,string);

void setContentLength(int length);

string getData();

};

#endif

正则表达式解析头部

由于我的gcc版本为4.4.7,无法使用c++11 标准正则表达式。这里就是用了boost的Regex库。使用方法和代码一致。关于正则表达式的知识大家可在正则表达式基础上学习。

前面我们学习到http请求数据格式为 起始行+首部+请求体。所以我们直接匹配第一行数据。然后将方法、路径匹配出来。

boost::regex reg("^(\\w+) /(\\w*([.]\\w+)?) HTTP/1");

boost::smatch sm;

regex_search(body,sm,reg);

if(sm.size()==0) {

return false;

}else{

cout<"<

method=sm[1];

path.clear();

path.append("/").append(sm[2]);

postfix=sm[3];

}

正则表达式括号的内容代表我们要匹配的字符串,sm的第一个下标数据是匹配的完整的字符串,所以我们从sm[1]开始取值。

请求文件读取

前面读取到请求路径后,我们就可以去读取对应文件。

//读写文件

int fileSize=0;

FILE *file=fopen(path.c_str(),"r");

if(file!=NULL) {

fseek(file,0L,SEEK_END);

//获取文件大小

fileSize=ftell(file);

fseek(file,0L,SEEK_SET);

}else{

cout<

}

接着就可以将文件数据发送出去

if(file!=NULL) {

char dataBuf[1024*100]={0};

while(true) {

int len= fread(dataBuf,1,sizeof(dataBuf),file);

if(len<=0) {

break;

}

cout<send Data "<

client->sendData(dataBuf,len);

}

fclose(file);

}

注意在发送文件数据前,我们先要想头部发送出去

resp.setContentLength(fileSize);

// if(sm[3].str().empty()) {

resp.addHead("Content-Type","text/html");

// }else{

// resp.addHead("Content-Type","image/jpeg");

// }

resp.addHead("Server","eric http");

string headsStr=resp.getData();

cout<

client->sendData(headsStr.c_str(),headsStr.size());

一个简单的http容器我们搭建完成了。接下来就是如何支持php。

php-cgi解析php文件

首先先要安装php。可以参考Linux下php安装

我们可以先写一个简单的php代码测试一下。

phpinfo();

?>

然后在命令行使用php-cgi

php-cgi index.php > index.php.html

成功生成了index.php.html。接下来我们回到代码:

if(req.getPostfix()==".php") {

string cmd="php-cgi ";

string resFilePath;

resFilePath.append(path).append(".html");

cmd.append(path).append(" > ").append(resFilePath);

cout<

system(cmd.c_str());

path=resFilePath;

}

首先我们判断请求路径的后缀是否为.php。如果是则执行php-cgi的命令并生成文件。然后得到文件路径,接下来就和正常读取文件并发送数据的流程一致了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值