由于经常需要这样一些场合,让应用程序能够响应简单的HTTP请求,以实现一些功能,所以就做了一个这样的小型HTTP服务器库。库使用C++实现,编译成MT,Release模式的静态链接库,欢迎有兴趣的朋友使用。该库仅适用Windows操作系统。
下面是库的定义:
#ifndef __HOVERLEES_TINY_HTTPD_H
#define __HOVERLEES_TINY_HTTPD_H
#include
#include
#include
struct HoverCompare{
bool operator()(const char* x, const char* y){
return strcmp(x,y)<0;
}
};
/**
* @name 嵌入应用程序的简单HTTP服务器
* @author Hoverlees http://www.hoverlees.com
* 调用者继承这个类以处理HTTP请求
*/
class TinyHttpd{
private:
static bool inited;
static WSADATA wsaData;
static DWORD WINAPI ServerThreadProc(void* lpParameter);
static DWORD WINAPI ClientThreadProc(void* lpParameter);
protected:
const static int STATUS_IDLE=0;
const static int STATUS_RUNNING=1;
typedef std::map hmap;
int status;
SOCKET serverSocket;
sockaddr_in address;
public:
TinyHttpd();
/**
* 启动服务器
* @param bindPort 梆定的HTTP端口
* @param bindIP 梆定IP地址
* @return 成功状态
*/
bool startServer(unsigned short bindPor=80,const char* bindIP="0.0.0.0");
/**
* 停止服务器
* @return 成功状态
*/
bool stopServer();
/**
* 向客户端发送应答,每一个请求只能调用一次这个函数。
* @param clientSocket 客户端socket
* @param mem 应答的内容
* @param memSize 应答内容大小
* @param response_headers HTTP响应头,如果不设置,可以为NULL
* @return 操作结果
*/
bool sendResponse(SOCKET clientSocket,const char* mem,int memSize,hmap* response_headers);
/**
* 回调方法,当服务器收到HTTP请求时,调用这个函数,注意TinyHttpd只支持GET请求
* @param clientSocket客户端socket,一般不直接操作,而是传入到sendResponse中。
* @param uri 请求uri,如客户端请求 /hoverlees?a=1&b=2 时,uri是 /hoverlees
* @param params 请求参数,这是HTTP get参数key=>value的map对象.如 params["a"]=1
* @return 如果用户处理了该请求,返回true,这时服务器响应200,如果没处理请求返回false ,服务器响应404
*/
virtual bool onHttpRequest(SOCKET clientSocket,const char* uri,hmap* params){return false;}
};
#endif
使用示例如下:
#include
#include
#include "TinyHttpd.h"
using namespace std;
#pragma comment(lib,"TinyHttpd.lib")
class MyHttpd:public TinyHttpd{
public:
MyHttpd():TinyHttpd(){
};
virtual bool onHttpRequest(SOCKET clientSocket,const char* uri,hmap* params){
void* mem;
FILE* fp;
hmap headers;
int fsize;
//可以先在这儿对uri指定的文件进行判断,如果文件存在,可以直接输出文件,这样就完全实现了一个静态网页的服务器。
if(strcmp(uri,"/hoverlees")==0){
if((*params)["hello"]){
//如果设置了hello参数,如:http://localhost/hoverlees?hello=1
this->sendResponse(clientSocket,"Hello World!",12,0);
}
else this->sendResponse(clientSocket,"Hoverlees",9,NULL);
}
else if(strcmp(uri,"/pic")==0){ //http://localhost/pic
fp=fopen("./1.png","rb");
fseek(fp,0,SEEK_END);
fsize=ftell(fp);
mem=malloc(fsize);
fseek(fp,0,SEEK_SET);
fread(mem,1,fsize,fp);
fclose(fp);
headers["Content-Type"]="image/png";
this->sendResponse(clientSocket,(char*)mem,fsize,&headers);
free(mem);
}
else if(strcmp(uri,"/")==0){
char* html="
hoverlees Picture";this->sendResponse(clientSocket,html,strlen(html),NULL);
}
else return false;
return true;
}
};
int main(int argc,char* argv[]){
//创建服务器
MyHttpd* httpd=new MyHttpd();
//启动服务器
httpd->startServer(80);
while(1){
Sleep(10000);
}
return 0;
}
相关的库文件和头文件在这里下载.test_app