基于的epoll模型的简单http服务器

本文详细介绍了如何基于边缘触发(ET)的epoll模型,实现一个简单的Linux多线程HTTP服务器。主线程负责监听事件并将其分配到线程池,线程池则处理具体的事件响应。
摘要由CSDN通过智能技术生成

  epoll模型主要有2种工作方式:水平触发(LT)和边缘触发(ET),本文主要是关于边缘触发的。本文实现的epoll多线程模型主要是,主线程等待事件触发,然后把相关事件放入队列,线程池从队列中取出数据处理事件。

下面是具体实现:

#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/epoll.h>
#include <sys/sendfile.h>
#include <dirent.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <signal.h>
#include <getopt.h>
#include <string.h>
#include <string>
#include <iostream>
#include "ThreadPool.h"
using namespace std;

static string strIP="192.168.0.168";
static int nPort=8088;
static  string strDir="/home/temp/http_server";
const int MAX_EVENT=10;
struct epoll_event ev, events[MAX_EVENT];
int epfd;
enum {NeedRead_Event,Reading_Event,Error_Req,NeedWrite_Event,Writing_Event};

struct Task
{
	epoll_event m_oEvent;
	string m_strFilePath;
	int m_nCurSize;
	int m_nType;
	int m_nReadOrWritefd;
	int m_nFileLen;
	int m_nSockfd;
};

char* dir_up(char *Path)
{
    int len;
    len = strlen(Path);
    if (len > 1 && Path[len - 1] == '/')
    {
        len--;
    }
    while (Path[len - 1] != '/' && len > 1)
    {
        len--;
    }
    Path[len] = 0;
    return Path;
}

char *strsplit(char **s,char del)
{
	char *d, *tok;
	if (!s || !*s)
		return NULL;
	tok = *s;
	d = strchr(tok, del);
	if (d) {
		*d = '\0';
		*s = d + 1;
	} else
		*s = NULL;
	return tok;
}
        
char* urldecode( char* encd, char* decd)   
{   
    int j,i;   
    char *cd = encd;   
    char p[2];   
    unsigned int num;   
    j=0;   
  
    for( i = 0; i < strlen(cd); i++ )   
    {   
        memset( p, '\0', 2 );   
        if( cd[i] != '%' )   
        {   
            decd[j++] = cd[i];   
            continue;   
        }   
    
  p[0] = cd[++i];   
        p[1] = cd[++i];   
  
        p[0] = p[0] - 48 - ((p[0] >= 'A') ? 7 : 0) - ((p[0] >= 'a') ? 32 : 0);   
        p[1] = p[1] - 48 - ((p[1] >= 'A') ? 7 : 0) - ((p[1] >= 'a') ? 32 : 0);   
        decd[j++] = (p[0] * 16 + p[1]);   
    
    }   
    decd[j] = '\0';   
  
    return decd;   
}  


void *ReadTask(void *arg)
{
	
	Task *pTask=(Task*)arg;
	char *cBuffer=new char[128*1024];
	if(pTask->m_nType==NeedRead_Event)
	{
		int nSize=read(pTask->m_nSockfd,cBuffer,128*1024);
		if(nSize==0)
		{
			close(pTask->m_nSockfd);
			epoll_ctl(epfd, EPOLL_CTL_DEL,pTask->m_nSockfd, &(pTask->m_oEvent));
			delete pTask;
			return NULL;
		}		
		else if(nSize<0)
		{
			cout<<errno<<endl;
			if (errno == EINTR)
			{
				pTask->m_oEvent.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
                                epoll_ctl(epfd, EPOLL_CTL_MOD,pTask->m_nSockfd, &(pTask->m_oEvent));
				return NULL;
                        }
                        if (errno == EAGAIN)
			{
				return NULL;
			}
		}
		else
		{
			char *cMethon=strsplit(&cBuffer,' ');
			if(cBuffer==NULL)
			{
				pTask->m_nType=E
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值