简单接受信息并发送html文本的http服务器

先定义一个锁类的头文件,其中包含互斥锁和信号量

#include <pthread.h>
#include <semaphore.h>
class locker{
    private:
        pthread_mutex_t mutex;
    public:
        locker()
        {
            pthread_mutex_init(&mutex,NULL);
        }
        ~locker()
        {
            pthread_mutex_destroy(&mutex);
        }
        bool lock()
        {
            return pthread_mutex_lock(&mutex)==0;
        }
        bool unlock()
        {
            return pthread_mutex_unlock(&mutex)==0;
        }
};
class sem{
    private:
        sem_t m_sem;
    public:
        sem()
        {
            sem_init(&m_sem,0,0);
        }
        ~sem()
        {
            sem_destroy(&m_sem);
        }
        bool wait()
        {
            return sem_wait(&m_sem);
        }
        bool post()
        {
            return sem_post(&m_sem);
        }
};

一个包含要处理的文件描述符类的头文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include <sys/epoll.h>
#include"epoller.h"
class basetask{
    private:
        int connfd;//客户端的文件描述符
    public:
        basetask(int a):connfd(a){}
        void work()
        {
            /*发送html文件*/
            int p=open("xia.html",O_RDONLY);
            char myhtml[1024];
            strcpy(myhtml,"HTTP/1.0 200 OK\r\n");
            strcat(myhtml,"Server: xiakaiwei\r\n");
            strcat(myhtml,"Content-type: text/html\r\n");
            strcat(myhtml,"Connection: close\r\n");
            char text[1024]={0};
            int read_size=read(p,text,sizeof(text)-1);
            char newbuff[1024];
            sprintf(newbuff,"Content-Length: %d\r\n\r\n",read_size);
            strcat(myhtml,newbuff);
            strcat(myhtml,text);
            write(connfd,myhtml,sizeof(myhtml));
            printf("html文本发送完毕\n");
            close(connfd);
        }

};

存放epollfd类的头文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include<sys/epoll.h>
class epoller{
    private:
        int epollfd;//事件监听空间
    public:
        epoller()
        {
            epollfd=epoll_create(5);
        }
        int getepollfd()
        {
            return epollfd;
        }
        int setnonblocking(int fd)
        {
            int old_option=fcntl(fd,F_GETFL);
            int new_option=old_option | O_NONBLOCK;
            fcntl(fd,F_SETFL,new_option);
            return old_option;
        }
        void addfd(int fd)
        {
            epoll_event event;
            event.data.fd=fd;
            event.events=EPOLLIN | EPOLLET;
            epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event);
            setnonblocking(fd);
        }
        void removefd(int fd)
        {
            epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,NULL);
            close(fd);
        }
};

线程池头文件

#include <pthread.h>
#include <algorithm>
#include <iostream>
#include "basetask.h"
#include <stdbool.h>
#include<list>
#include"locker.h"
using namespace std;
class threadpool{
    private:
        list<basetask*>Task;
        locker list_lock;
        sem list_sem;
    public:
        threadpool()
        {
            this->createthread();
        }
        bool isempty()
        {
            return this->Task.empty();
        }
        void createthread()
        {
            pthread_t id;
            for(int i=0;i<8;i++)
            {
                pthread_create(&id,NULL,runthread,this);
            }
        }
        basetask* poptask()
        {
            list_lock.lock();
            basetask *end=Task.front();
            Task.pop_front();
            list_lock.unlock();
            return end;
        }void pushback(int fd)
        {
            basetask *task=new basetask(fd);
            list_lock.lock();
            Task.push_back(task);
            cout<<"此时任务队列个数:"<<Task.size()<<endl;
            list_lock.unlock();
            list_sem.post();
        }
    private:
        static void *runthread(void *poll)
        {
            threadpool *p=(threadpool*)poll;
            pthread_detach(pthread_self());
            while(1)
            {
                p->list_sem.wait();
                basetask *task=p->poptask();
                cout<<"线程"<<pthread_self()<<"取得任务"<<endl;
                task->work();
            }
            


        }
};

main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include"threadpool.h"

int init()
{
    int listenfd;
    struct sockaddr_in server_address;
    memset(&server_address,0,sizeof(server_address));
    server_address.sin_addr.s_addr=inet_addr("127.0.0.1");
    server_address.sin_family=PF_INET;
    server_address.sin_port=htons(atoi("80"));
    listenfd=socket(PF_INET,SOCK_STREAM,0);
    if(listenfd==-1)
    {
        printf("socket error!\n");
    }
    int ret=bind(listenfd,(struct sockaddr *)&server_address,sizeof(server_address));
    if(ret==-1)
    {
        printf("bind erroe!\n");
    }
    ret=listen(listenfd,5);
    if(ret==-1)
    {
        printf("listen error!\n");
    }
    return listenfd;
}

int main()
{
    int listenfd=init();
    epoller epo;
    epo.addfd(listenfd);
    epoll_event events[8];
    while(1)
    {
        int numbers=epoll_wait(epo.getepollfd(),events,8,-1);
        for(int i=0;i<numbers;i++)
        {
            int sockfd=events[i].data.fd;
            if(sockfd==listenfd)
            {
                struct sockaddr_in client_address;
                socklen_t client_address_len=sizeof(client_address);
                int client_sockfd=accept(listenfd,(struct sockaddr*)&client_address,&client_address_len);
                epo.addfd(client_sockfd);
            }
            else if(events[i].events & EPOLLIN)
            {
                printf("可读\n");
                while(1)
                {
                    char buff[1024];
                    int revc_size=recv(sockfd,buff,sizeof(buff),0);
                    if(revc_size>0)
                    {
                        printf("%s\n",buff);
                    }
                    else if(revc_size==0)
                    {
                        printf("连接关闭\n");
                        break;
                    }
                    else
                    {
                        break;
                    }
                
                }
                threadpool*pool=new threadpool;
                pool->pushback(sockfd);
            }
        }
    }
    

    
}

主函数采用reactor模式网页发送GET请求后,主函数将basetask放入任务队列中并释放信号量,线程池中线程等待信号量的释放,其中之一的线程争抢到锁后进行工作。

在firefox中输入127.0.0.1后可以看到,终端收到了两个GET请求并将内容打印了出来,然后发送了一个简单的html文本。

(没搞懂网页发送的第二个GET请求是什么意思)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

"情歌被打败"

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值