基于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释放资源。虽然这样使得
new
与delete
分离,但是可以保证程序的正常运行。线程池结束后,需要唤醒阻塞中的所有线程,以使其正常退出。
具体实现细节
由于在实现线程池时,需要用到任务队列,为保证任务队列在添加、删除元素时不会出错,需要对其加锁;同样由于在线程池中线程的运行与否需要受到控制,因此需要使用条件变量来使线程保持同步。所以在
locker.h
中定义了两个类:互斥锁、条件变量。互斥锁比较简单,所以说一下条件变量需要注意的细节:- 条件变量需要与互斥锁配合使用。由于条件变量的操作并非原子操作,因此在进行相关变量状态转变的时候,多线程若操作统一条件变量会造成错误。因此在条件变量之前需要加互斥锁进行保护,结束后及时解锁。
由于每次接收到数据时,需要新建一个任务,因此在
task.h
中定义一个封装任务信息的类。该类负责接受来自浏览器具体的请求信息,再进行解析,根据对应的结果进行处理与返回网页信息等。- 由于在任务结束后会调用delete,从而会进行析构,因此可以在Task的析构函数中关闭连接。即每个任务(每个HTTP请求)对应一个线程,每次任务结束后都会关闭与浏览器连接。
- 在每次任务执行时,为避免读取数据出错,需要循环读取,直到对方关闭连接(recv返回值=0)或请求处理完成后退出循环,即一次任务完成后也要退出循环。PS:一定要注意关闭连接的时间,否则浏览器会一直处于pending状态
threadPool.h
存放线程池的定义与实现。线程池提供线程的调度,及时处理任务队列中的任务;若任务队列为空,则所有线程处于阻塞状态。由于使用模板类,因此需要将类定义与方法实现放在一个文件夹下,因为模板类的成员函数不能单独编译。详见我的另一篇博客:线程池的分析与实现。webServer.h
与webServer.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高性能服务器编程》
基于epoll+threadpool的webServer分析与实现相关推荐
- 基于Epoll的Reactor模式
Reactor模式 Reactor模式的定义 Reactor模式中的主要角色 Epoll (ET)服务器 EventItem类的设计 Reactor类的设计 回调函数 套接字相关 引入线程池 Reac ...
- 基于itchat的个人情感分析
基于itchat的个人情感分析 昝道广 概述 前言 思考 性别分析 好友签名情感分析 地区分布 爬虫技术分析 代码解析(部分) 后记 前言 本文以迅雷不及掩耳盗铃儿响叮当机立断章取义无反顾,雄姿英发, ...
- 有源淹没分析arcgis_基于ArcGIS的洪水淹没分析与三维模拟
基于 ArcGIS 的洪水淹没分析与三维模拟 孙 君 , 奚赛英 , 尤 迪 , 郑付涛 [摘 要] 摘 要 : 洪水淹没范围的确定是洪灾损失评估和防洪决策的核心环节 . 基 于 TIN 数据 , 运 ...
- 基于linux服务器的性能分析与优化
基于linux服务器的性能分析与优化 方面:硬件系统软件网络 现象:系统不稳定相应速度慢 web无法打开打开速度慢 方案:硬件故障更换硬件或升级硬件 系统问题修改系统参数和配置 软件问题修改和升级软件 ...
- 子空间迭代法 matlab,基于MATLAB的一类迭代分析
一般的计算方法教程如文献[1-5]都会介绍三种常见的迭代法,即Jacobi方法.Gauss-Seidel方法和SOR迭代.由于Gauss-Seidel方法充分利用了迭代过程的新信息[1,2],一般来说 ...
- 基于epoll实现简单的web服务器
1. 简介 epoll 是 Linux 平台下特有的一种 I/O 复用模型实现,于 2002 年在 Linux kernel 2.5.44 中被引入.在 epoll 之前,Unix/Linux 平台下 ...
- 网站数据分析:基于用户细分的比较分析
从网站的用户层面,我们根据用户访问的行为特征将用户细分成各种类型,因为用户行为各异,行为统计指标各异,分析的角度各异,所以如果要对用户做细 分,可以从很多角度根据各种规则实现各种不同的分类,看到过有些 ...
- 快速谱峭度matlab,一种基于快速谱峭度分析的泵潜在空化故障检测方法与流程
本发明属于信号处理领域,尤其涉及一种基于快速谱峭度分析泵的实时状态并且检测其潜在空化故障的方法. 背景技术: 高性能离心泵在当今社会上广泛应用和需求巨大.由于工作在高压高速等复杂条件下,离心泵的空化故 ...
- 网络安全模型_基于数据驱动的网络安全流量分析总结
导读 网络和社交流量分析是检测和防御网络攻击的基础.随着数据集的日益剧增,手工定义规则的传统方法逐渐被机器学习(ML)方法替代,这是因为ML有更好的工作性能.在数据驱动的研究背景下,通过研究社交流量和 ...
最新文章
- redis有几种数据类型
- 创建 OVS vlan101 并部署 instance - 每天5分钟玩转 OpenStack(139)
- U盘为什么还有剩余空间,但却提示说空间不够
- linux桥接实现交换机功能
- (转)编写可重入和线程安全的代码(Writing Reentrant and Thread-Safe Code)
- 插入排序法(思路及代码实现)
- 家庭财务管理系统_我31岁,30天整理出这些财务笔记干货,从宝妈成功逆袭成为会计...
- oracle_监听器无法启动的问题
- 《科学+ 预见人工智能》——物理学家的管理方式
- 点击Result list里product ID出现白屏的又一原因及分析
- linux下无法umount移动设备
- linux+vim+动不了,linux的vim按了ctrl+s之后假死的解决办法
- logistic regression一点理解
- HTML5---新标签与特性
- linux下重启weblogic
- 数据结构开发(6):静态单链表的实现
- 信捷plc用c语言编程视频,信捷PLC/触摸屏全套编程软件/学习教程视频资料 大全编程操作手册...
- centos7搭建使用花生壳
- uniapp使用高德地图
- iOS 10版本适配