基于epoll+threadpool的webServer分析与实现

该webServer使用epoll+threadpool实现,支持GET、POST方法,并添加CGI进行数据计算并返回网页信息,可以解析返回html、picture、mp3、js、css等文件,可以实现稳定的运行。 使用c++编写。

源码请看我的Github

流程简述

  • 启动服务器,在浏览器输入服务器地址,将向服务器发送HTTP请求

  • 服务器接收数据,新建任务,将任务添加到任务队列

  • 从线程池中唤醒某线程,执行任务。若没有任务线程会处于wait状态;若任务过多,会存储在任务队列中,等待空闲线程来执行

  • 某线程获得任务后,读取浏览器发送的请求信息,进行解析HTTP首部,根据对应的结果来进行相应的处理,返回信息,若文件不存在则返回404.html,若请求方法不存在则返回501错误信息。

  • 若是POST,则需要调用CGI进行处理,并返回相应的信息。

  • 任务结束后,需要进行delete,因为在主进程中,为避免任务未运行完便被析构,需要使用new来新建对象,为避免内存泄露,需要在任务结束后使用delete释放资源。虽然这样使得newdelete分离,但是可以保证程序的正常运行。

  • 线程池结束后,需要唤醒阻塞中的所有线程,以使其正常退出。

具体实现细节

  • 由于在实现线程池时,需要用到任务队列,为保证任务队列在添加、删除元素时不会出错,需要对其加锁;同样由于在线程池中线程的运行与否需要受到控制,因此需要使用条件变量来使线程保持同步。所以在locker.h中定义了两个类:互斥锁、条件变量。互斥锁比较简单,所以说一下条件变量需要注意的细节:

    • 条件变量需要与互斥锁配合使用。由于条件变量的操作并非原子操作,因此在进行相关变量状态转变的时候,多线程若操作统一条件变量会造成错误。因此在条件变量之前需要加互斥锁进行保护,结束后及时解锁。
  • 由于每次接收到数据时,需要新建一个任务,因此在task.h中定义一个封装任务信息的类。该类负责接受来自浏览器具体的请求信息,再进行解析,根据对应的结果进行处理与返回网页信息等。

    • 由于在任务结束后会调用delete,从而会进行析构,因此可以在Task的析构函数中关闭连接。即每个任务(每个HTTP请求)对应一个线程,每次任务结束后都会关闭与浏览器连接。
    • 在每次任务执行时,为避免读取数据出错,需要循环读取,直到对方关闭连接(recv返回值=0)或请求处理完成后退出循环,即一次任务完成后也要退出循环。PS:一定要注意关闭连接的时间,否则浏览器会一直处于pending状态
  • threadPool.h存放线程池的定义与实现。线程池提供线程的调度,及时处理任务队列中的任务;若任务队列为空,则所有线程处于阻塞状态。由于使用模板类,因此需要将类定义与方法实现放在一个文件夹下,因为模板类的成员函数不能单独编译。详见我的另一篇博客:线程池的分析与实现

  • webServer.hwebServer.cpp存放WebServer类的定义与实现。该类主要进行socket的创建,绑定,监听,与accept,使用epoll实现。在接收到新连接时,将fd注册到内核事件表;有数据写入时,便使用new新建任务,并添加到线程池。由于任务使用new创建,因此任务结束后需要及时delete task。

使用介绍

  • 由于在上传时,将mp3文件删除(上传缓慢),因此需要在与index.html同级的目录下放一个mp3文件,并命名为1.mp3

  • 打开终端,在makefile目录下,输入./server port以运行服务器,其中port为端口号,以下以8080端口为例:
    终端输入 :

./server 8080

打开浏览器,在网址输入:

localhost:8080

或输入网址:

127.0.0.1:8080

即可连接服务器。

  • 如果要使用自己的网页,只要将网页放到与webServer.cpp统一目录下,把index.html用新的主页覆盖即可。

参考:《Linux高性能服务器编程》

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值