本文没有带反射部分内容,可以看我之前发的
Server.h
#pragmaonce#include<string>#include<iostream>#include<thread>#include<unordered_map>usingnamespace std;#ifndef_SERVER_#define_SERVER_#include<winsock.h>#include"Net.h"#include"Util.h"#pragmacomment(lib,"ws2_32.lib")NAME_SPACE_START(myUtil)#defineSERVER_ADDR"127.0.0.1"#defineSERVER_PORT8080classServer{public:Server();Server(const std::string& addr = SERVER_ADDR,constint& port = SERVER_PORT);~Server(){}public:boollisten(constint& maxConnect =1);voidsetRoute(const string& url,const string& className,const string& classFunName);voidrunRoute(const Request& req, Response* resp);voidsetInterceptor(const string& url,const string& InterceptorName);voidclose();protected:boolInit();voidthreadFunc(SOCKET m_server);intsendTelegram(const SOCKET& accept,const string& info,int flags);private:
SOCKET m_server;
SOCKADDR_IN m_add_in;//thread listenThread;int connectCount{0};
unordered_map<string, pair<string, string>> routeMap;
unordered_map<string, string> interceptorMap;
IniHelper iniHelper;};NAME_SPACE_END()#endif//!_SERVER_
Server.cpp
#include"Server.h"#include<minwindef.h>#include<string>#include<winsock.h>#include<iostream>#include<thread>#include<fstream>#include"Net.h"#include"Util.h"#include"Reflex.h"#include"CController.h"#include"Interceptor.h"usingnamespace std;NAME_SPACE_START(myUtil)Server::Server(){
m_add_in.sin_family = AF_INET;
m_add_in.sin_addr.S_un.S_addr =htonl(INADDR_ANY);
m_add_in.sin_port =htons(SERVER_PORT);}Server::Server(const std::string& addr,constint& port){
m_add_in.sin_family = AF_INET;
m_add_in.sin_addr.S_un.S_addr =inet_addr(addr.c_str());
m_add_in.sin_port =htons(port);}boolServer::listen(constint& maxConnect){if(!Init()){returnfalse;}
m_server =socket(AF_INET, SOCK_STREAM,0);if(::bind(m_server,(sockaddr*)&m_add_in,sizeof(SOCKADDR))== SOCKET_ERROR){WSACleanup();returnfalse;}if(::listen(m_server, maxConnect)<0){WSACleanup();returnfalse;}
thread listenThread(&Server::threadFunc,this, m_server);
listenThread.join();returntrue;}voidServer::setRoute(const string& url,const string& className,const string& classFunName){
routeMap.insert(pair<string, pair<string, string>>(url,pair<string, string>(className, classFunName)));}voidServer::runRoute(const Request& req, Response* resp){
string url = req.getRequestStatus().Url;
Reflex* factory = myUtil::Singleton<Reflex>::Instance();
string interceptorName ="";
string res ="";
string content ="";//拦截器//先去拦截器映射表中寻找类名,没有的话默认使用基类auto interceptorIt = interceptorMap.find(url);if(interceptorIt != interceptorMap.end()) interceptorName = interceptorIt->second;
Interceptor* inter =(Interceptor*)factory->createClass(interceptorName);if(inter ==nullptr) inter =newInterceptor();if(inter->preHandle(req,*resp)){//反射auto it = routeMap.find(url);if(it != routeMap.end()){
CController* cont =(CController*)factory->createClass(it->second.first);
res = cont->Call<string, Request, Response*>(it->second.second, req, resp);}//反射结束}else{
resp->setResponseStatus("HTTP",1,1,404,"Forbidden");}if(url.find("favicon.ico")!= string::npos){
content =getFile(iniHelper.getIniConfig("staticResource","favicon_path","./favicon.ico"));
resp->setResponseHead("content-type","image/x-icon");}elseif(res !=""){try{
content =getFile(res);}catch(exception ex){
content = ex.what();}}
resp->setResponseContent(content);auto list = resp->getCookie();for(auto item : list){
resp->setResponseHead("Set-Cookie", item.toString());}
resp->setResponseHead("content-length",to_string(content.size()));
resp->setResponseHead("Server","C++MVC");
inter->postHandle(req,*resp);}voidServer::setInterceptor(const string& url,const string& InterceptorName){
interceptorMap.insert(pair<string, string>(url, InterceptorName));}voidServer::close(){closesocket(m_server);WSACleanup();}boolServer::Init(){
WORD ver =MAKEWORD(2,2);
WSADATA wsadata;int errFlag =-1;
errFlag =WSAStartup(ver,&wsadata);if(errFlag !=0)returnfalse;//检测版本号if(LOBYTE(wsadata.wVersion)!=2||HIBYTE(wsadata.wHighVersion)!=2){WSACleanup();returnfalse;}returntrue;}voidServer::threadFunc(SOCKET m_server){while(1){
SOCKADDR_IN m_acc_in;int len =sizeof(SOCKADDR);
SOCKET m_accept =accept(m_server,(sockaddr*)&m_acc_in,&len);if(m_accept == SOCKET_ERROR){continue;}int recv_len =0;char recv_buf[10000];
recv_len =recv(m_accept, recv_buf,10000,0);//char 转 wcharint unicodeLen =::MultiByteToWideChar(CP_UTF8,0, recv_buf,-1,NULL,0);wchar_t* pUnicode =newwchar_t[unicodeLen];memset(pUnicode,0, unicodeLen *sizeof(wchar_t));::MultiByteToWideChar(CP_UTF8,0, recv_buf,-1,(LPWSTR)pUnicode, unicodeLen);
wstring rt = pUnicode;//重设大小char* pAscii =newchar[recv_len];memset(pAscii,0,sizeof(char)* recv_len);strncpy(pAscii, recv_buf, recv_len);
string lrt(pAscii);//解析请求
Request req(lrt);
Response resp;runRoute(req,&resp);
cout <<"请求地址:"<< req.getRequestStatus().Url << endl;sendTelegram(m_accept, resp.toString(),0);closesocket(m_accept);}}intServer::sendTelegram(const SOCKET& accept,const string& info,int flags){int res =send(accept, info.c_str(), info.size(), flags);return res;}NAME_SPACE_END()
Interceptor.h
#pragmaonce#include"Net.h"#include"Reflex.h"usingnamespace myUtil;#ifndef_INTERCEPTOR_#define_INTERCEPTOR_classInterceptor:publicRObject{public:virtualboolpreHandle(const Request& request,const Response& response){returntrue;}virtualvoidpostHandle(const Request& request,const Response& response){}virtualvoidafterCompletion(const Request& request,const Response& response){}};#endif//!_INTERCEPTOR_
indexInterceptor.h
#pragmaonce#include"Interceptor.h"classIndexInterceptor:publicInterceptor{public:boolpreHandle(const Request& request,const Response& response)override{returnfalse;}voidpostHandle(const Request& request,const Response& response)override{}voidafterCompletion(const Request& request,const Response& response)override{}};
InterceptorMacro.h
#pragmaonce#include"Reflex.h"#include"indexInterceptor.h"#defineREFLEX_INPERCEPTOR_DECLARE\REGISTER_REFLEX(IndexInterceptor)
Cookie.h
#pragmaonce#ifndef_COOKIE_#define_COOKIE_#include<string>usingnamespace std;classCookie{public:Cookie(){}Cookie(const string& name,const string& value):_name(name),_value(value){
_comment ="";
_path ="";
_domain ="";
_version ="";
_maxAge =0;}
string getNameValue()const;voidsetNameValue(const string& name,const string& value);voidsetComment(const string& comment);voidsetPath(const string& path);voidsetDomain(const string& domain);voidsetVersion(const string& version);voidsetMaxAge(constint& maxAge);
string getComment()const;
string getPath()const;
string getDomain()const;
string getVersion()const;intgetMaxAge()const;
string toString()const;private:
string _name;
string _value;//注释
string _comment;//路径,若要访问的url startwith(path)此cookie携带
string _path;//网站域名
string _domain;
string _version;//生存时间int _maxAge{0};};#endif//!_COOKIE_
Cookie.cpp
#include"Cookie.h"
string Cookie::getNameValue()const{return _name +"="+ _value;}voidCookie::setNameValue(const string& name,const string& value){
_name = name;
_value = value;}voidCookie::setComment(const string& comment){
_comment = comment;}voidCookie::setPath(const string& path){
_path = path;}voidCookie::setDomain(const string& domain){
_domain = domain;}voidCookie::setVersion(const string& version){
_version = version;}voidCookie::setMaxAge(constint& maxAge){
_maxAge = maxAge;}
string Cookie::getComment()const{return _comment;}
string Cookie::getPath()const{return _path;}
string Cookie::getDomain()const{return _domain;}
string Cookie::getVersion()const{return _version;}intCookie::getMaxAge()const{return _maxAge;}
string Cookie::toString()const{
string res =getNameValue();if(_comment !="") res +=";comment="+ _comment;if(_path !="") res +=";Path="+ _path;if(_domain !="") res +=";Domain="+ _domain;if(_version !="") res +=";Version="+ _version;
res +=";Max-Age="+ _maxAge;return res;}
CController.h
#pragmaonce#ifndef_CCONTROLLER_#define_CCONTROLLER_#include"Reflex.h"usingnamespace myUtil;classCController:publicRObject{};#endif//!_CCONTROLLER_
indexController.h
#pragmaonce#include"CController.h"#include"Net.h"#include"Reflex.h"usingnamespace myUtil;classindexController:publicCController{public:indexController(){}~indexController(){}
string index(const Request& req, Response* resp);
string test(const Request& req, Response* resp);};
indexController.cpp
#include"indexController.h"#include<fstream>usingnamespace std;
string indexController::index(const Request& req, Response* resp){
resp->setResponseStatus("HTTP",1,1,200,"OK");
resp->setResponseHead("Content-Type","text/html,charset=UTF-8");return"index.html";}
string indexController::test(const Request& req, Response* resp){
resp->setResponseStatus("HTTP",1,1,200,"OK");
resp->setResponseHead("Content-Type","text/html,charset=UTF-8");
Cookie cookie("test","test");
cookie.setDomain("localhost");
cookie.setMaxAge(10);
cookie.setPath("/test");
resp->setCookie(cookie);return"test.html";}
ControllerMacro.h
#pragmaonce#include"indexController.h"#defineREFLEX_DECLARE\REGISTER_REFLEX(indexController)\REGISTER_REFLEX_METHOD_ARGS(indexController, index, string, Request&, Response*)\REGISTER_REFLEX_METHOD_ARGS(indexController, test, string, Request&, Response*)
Net.h
#pragmaonce#ifndef_NET_#define_NET_#include<string>#include<wtypes.h>#include<unordered_map>#include"Util.h"#include"Cookie.h"usingnamespace std;NAME_SPACE_START(myUtil)#defineBLACK"\r\n"#defineSPACE" "classNet{public:virtual string toString()=0;virtual vector<Cookie>getCookie()const=0;virtualvoidsetCookie(const Cookie& cookie)=0;Net(){}protected:
vector<Cookie> _cookie;};structRequestStatus{
string RMethod;
string Url;
string ProName;short verHigh;short verLow;};structResponseStatus{
string ProName;short verHigh;short verLow;short status;
string statusWord;};//请求classRequest:publicNet{public:Request();Request(const string& sourceStr);voidsetRequestStatus(const string& method ="GET",const string& url ="/",const string& _proName ="HTTP",constshort& _verHigh =1,constshort& _verLow =1);voidsetRequestHead(const string& headKey,const string& headValue);voidsetRequestContent(const string& content);
RequestStatus getRequestStatus()const;
string getRequestContent(const string& headKey)const;
vector<Cookie>getCookie()constoverride;voidsetCookie(const Cookie& cookie)override;
string toString()override;~Request(){}private:
RequestStatus _status;
unordered_map<string, string> _RequestHead;
string _RequestContent{""};};//响应//结构 状态行, 响应头部, 空行, 响应正文classResponse:publicNet{public:Response();voidsetResponseStatus(const string& _proName ="HTTP",constshort& _verHigh =1,constshort& _verLow =1,constshort& status =200,const string& word ="");voidsetResponseHead(const string& headKey,const string& headValue);voidsetResponseContent(const string& content);
ResponseStatus getResponseStatus()const;
string getResponseHeadByKey(const string& headKey)const;
vector<Cookie>getCookie()constoverride;voidsetCookie(const Cookie& cookie)override;
string toString()override;~Response();private:
ResponseStatus _status;
unordered_map<string, string> _ResponseHead;
string _ResponseContent{""};};classAnalyse{public:static vector<string>getVectorBySplit(const string& source,constchar& ch);static unordered_map<string, string>getMapBySplit(const string& source,constchar& ch1,constchar& ch2);static string makeVectorByChar(const vector<string>& v,constchar& ch);static string makeMapByChars(const unordered_map<string, string>& m,constchar& ch1,constchar& ch2);};NAME_SPACE_END()#endif//!_NET_
Net.cpp
#include"Net.h"NAME_SPACE_START(myUtil)Response::Response(){
_status.ProName ="HTTP";
_status.verHigh =1;
_status.verLow =1;
_status.status =200;
_status.statusWord ="OK";}voidResponse::setResponseStatus(const string& _proName,constshort& _verHigh,constshort& _verLow,constshort& status,const string& word){
_status.ProName = _proName;
_status.verHigh = _verHigh;
_status.verLow = _verLow;
_status.status = status;
_status.statusWord = word;}voidResponse::setResponseHead(const string& headKey,const string& headValue){
_ResponseHead.insert(pair<string, string>(headKey, headValue));}voidResponse::setResponseContent(const string& content){
_ResponseContent = content;}
ResponseStatus Response::getResponseStatus()const{return _status;}
string Response::getResponseHeadByKey(const string& headKey)const{auto it = _ResponseHead.find(headKey);if(it == _ResponseHead.end())return"";return(*it).second;}
vector<Cookie>Response::getCookie()const{return _cookie;}voidResponse::setCookie(const Cookie& cookie){
_cookie.push_back(cookie);}
string Response::toString(){
string res ="";
res += _status.ProName +"/"+to_string(_status.verHigh)+"."+to_string(_status.verLow)+ SPACE +to_string(_status.status)+ SPACE + _status.statusWord + BLACK;for(auto it = _ResponseHead.begin(); it != _ResponseHead.end(); it++){
res +=(*it).first +":"+ SPACE +(*it).second + BLACK;}
res += BLACK;
res += _ResponseContent;return res;}Response::~Response(){}Request::Request(const string& sourceStr){int i =0;
vector<string> reqGroup =Analyse::getVectorBySplit(sourceStr,'\n');//解析状态行
vector<string> statuses =Analyse::getVectorBySplit(reqGroup[0],' ');
_status.RMethod = statuses.at(0);
_status.Url = statuses.at(1);
statuses.at(2).pop_back();
vector<string> verInfo =Analyse::getVectorBySplit(statuses.at(2),'/');
_status.ProName = verInfo.at(0);
_status.verHigh =Analyse::getVectorBySplit(verInfo.at(1),'.').at(0).at(0)-'0';
_status.verLow =Analyse::getVectorBySplit(verInfo.at(1),'.').at(1).at(0)-'0';//解析请求头for(i =1; i < reqGroup.size(); i++){if(reqGroup[i]=="\r")break;
reqGroup[i].pop_back();
vector<string> temp =Analyse::getVectorBySplit(reqGroup[i],':');
_RequestHead.insert(pair<string, string>(temp.at(0), temp.at(1)));}
i++;for(i; i < reqGroup.size(); i++){
_RequestContent += reqGroup.at(i)+"\n";}}voidRequest::setRequestStatus(const string& method,const string& url,const string& _proName,constshort& _verHigh,constshort& _verLow){
_status.RMethod = method;
_status.Url = url;
_status.ProName = _proName;
_status.verHigh = _verHigh;
_status.verLow = _verLow;}voidRequest::setRequestHead(const string& headKey,const string& headValue){
_RequestHead.insert(pair<string, string>(headKey, headValue));}voidRequest::setRequestContent(const string& content){
_RequestContent = content;}
RequestStatus Request::getRequestStatus()const{return _status;}
string Request::getRequestContent(const string& headKey)const{return _RequestContent;}
string Request::toString(){
string res ="";
res += _status.RMethod + SPACE + _status.Url + SPACE + _status.ProName +"/"+to_string(_status.verHigh)+"."+to_string(_status.verLow)+ BLACK;for(auto it = _RequestHead.begin(); it != _RequestHead.end(); it++){
res +=(*it).first +":"+ SPACE +(*it).second + BLACK;}
res += BLACK;
res += _RequestContent;return res;}
vector<Cookie>Request::getCookie()const{return _cookie;}voidRequest::setCookie(const Cookie& cookie){
_cookie.push_back(cookie);}
vector<string>Analyse::getVectorBySplit(const string& source,constchar& ch){
vector<string> res;
string temp ="";for(int i =0; i < source.size(); i++){if(source[i]== ch){
res.push_back(temp);
temp ="";}else{char ch = source[i];
temp.push_back(ch);}}if(temp !="") res.push_back(temp);return res;}
unordered_map<string, string>Analyse::getMapBySplit(const string& source,constchar& ch1,constchar& ch2){
unordered_map<string, string> res;
vector<string> temp =getVectorBySplit(source, ch1);for(string str : temp){
vector<string> t =getVectorBySplit(str, ch2);if(t.size()!=2)continue;
res.insert(pair<string, string>(t.at(0), t.at(1)));}return res;}
string Analyse::makeVectorByChar(const vector<string>& v,constchar& ch){
string res ="";for(auto str : v){
res += str + ch;}
res.pop_back();return res;}
string Analyse::makeMapByChars(const unordered_map<string, string>& m,constchar& ch1,constchar& ch2){
string res ="";for(auto it = m.begin(); it != m.end(); it++){
res += it->first + ch2 + it->second + ch1;}
res.pop_back();return res;}NAME_SPACE_END()
config.ini
[staticResource]
favicon_path=./ico/favicon.ico
使用方式如下
通过setRoute设置路由规则,类似于springboot中的注释部分
通过setInterceptor设置拦截器规则,如果没有设置的话,会默认找基类
以上两个设置之后还要再两个macro文件中设置宏展开,否则反射找不到对应的类,关于反射如何使用请看这个
https://blog.csdn.net/weixin_43891802/article/details/129411364
#include<iostream>#include<string>#include"ControllerMacro.h"#include"InterceptorMacro.h"#include"Server.h"usingnamespace std;usingnamespace myUtil;
REFLEX_DECLARE
REFLEX_INPERCEPTOR_DECLARE
intmain(){
Server server("127.0.0.1",8080);
server.setRoute("/","indexController","index");
server.setRoute("/test","indexController","test");//server.setInterceptor("/test", "IndexInterceptor");
server.listen(2);return0;}
版权归原作者 咩~~ 所有, 如有侵权,请联系我们删除。