![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
webServer
文章平均质量分 78
{(sunburst)}
emmmmm
展开
-
Linux多线程Web服务器(C++实现)
如果全部写完了,需要判断是否建立了HTTP长连接,如果建立了,那么就要尽量在一个TCP连接内完成多条HTTP报文的传送,所以进入process函数,判断此时收集到的请求是否可以成功解析,如果成功则继续监听EPOLLOUT,让本条请求的响应在下一轮epoll_wait中就绪,如果失败,说明此时收集到的请求仍然不足,改为监听EPOLLIN,继续读取客户端请求。当然,本文实现的基于多线程的Web服务器,一旦主线程的监听服务器终止,派生的子线程也会随之终止,大家都关闭了,也就不存在上述的重启失败问题。原创 2023-01-13 12:27:53 · 1998 阅读 · 0 评论 -
HTTP连接(读取请求+解析请求+生成响应+回送响应)
通过ssize_t HttpConn::read(int* errno_) +bool HttpConn::process()函数+上面的ssize_t HttpConn::write(int* errno_)函数完成。因为生成请求的部分将响应头置于缓冲区buffer内,将响应体即要回送的文件,通过mmap方式建立了内存映射,获得一个指向被映射区的指针char* mmFile。给struct iovec vec[2] 赋值,vec[0]保存响应头的首地址和长度,vec[1]保存响应体的首地址和长度。原创 2023-01-12 20:48:53 · 735 阅读 · 2 评论 -
生成HTTP响应报文
提取path的后缀,然后利用哈希表SUFFIX_TYPE,得到对应值(例如:文件后缀为html,则对应值应为text/html )根据请求写出相应的HTTP响应头,然后再将path上的文件置于响应体,通过socket发往客户端。本文实现的响应头,包含200、400、403、404四种状态码及其对应的原因短语,响应头部分有。其余是响应头,由头部字段名称(Connection) :值(keep-alive) 构成。响应体内应为path对应的文件,为了提高服务器从磁盘中读取响应文件的速度,采用。原创 2023-01-12 18:07:15 · 847 阅读 · 0 评论 -
解析HTTP请求报文(GET、POST)
使用状态机和正则表达式完成了对HTTP请求报文的解析,支持解析GET报文和POST报文(仅限Content-Type: application/x-www-form-urlencoded)。由于计划完成的web服务器需要实现展示主页(GET)用户登录(POST)用户注册(POST)获取图片(GET)获取视频(GET)五个功能,所以web服务器的请求解析模块满足:若为GET请求,可根据状态行信息,完成对请求内容地址的转换,以及请求头内其他内容的提取。若为POST请求。原创 2023-01-05 23:02:26 · 7557 阅读 · 4 评论 -
数据库连接池(C++11实现)
1、初始连接数(initSize):初始连接量表示连接池事先会和MySQL Server创建的initSize数量的SqlConn连接。在完成初始连接量之后,当应用发起MySQL访问时,不用创建新的MySQLServer连接,而是从连接池中直接获取一个连接,当使用完成后,再把连接归还到连接池中。2、最大容量(maxCapacity)连接池的最大容量即连接池内的最大连接数。原创 2023-01-01 19:02:30 · 1215 阅读 · 3 评论 -
同步+异步日志系统(C++实现)
对于一个服务器而言,不论是在调试中还是在运行中,都需要通过打日志的方式来记录程序的运行情况。日志写入函数与工作线程串行执行,由于涉及到I/O操作,当单条日志比较大的时候,同步模式会阻塞整个处理流程,服务器所能处理的并发能力将有所下降,尤其是在峰值的时候,写日志可能成为系统的瓶颈。将所写的日志内容先存入中,写线程从阻塞队列中取出内容,写入日志。原创 2023-01-01 12:37:03 · 4486 阅读 · 5 评论 -
基于C++11的线程池实现(ThreadPool)
线程池: 当进行并行的任务作业操作时,线程的建立与销毁的开销是阻碍性能进步的关键,因此需要在线程池内创建多个线程,无限循环从任务队列中取走任务并执行,提高性能。原创 2022-12-26 21:32:24 · 815 阅读 · 3 评论 -
基于C++11实现的阻塞队列(BlockQueue)
当缓冲区满的时候,生产者会进入阻塞状态,当下次消费者开始消耗缓冲区的数据时,生产者才会被唤醒,开始往缓冲区中添加数据;当缓冲区空的时候,消费者也会进入阻塞状态,直到生产者往缓冲区中添加数据时才会被唤醒。因为要实现线程安全的函数,所以将pop函数的接口设计为需要放入一个自己的T item作为删除数据的拷贝。生产者不会在缓冲区满的时候继续向缓冲区放入数据,而消费者也不会在缓冲区空的时候,消耗数据。1、析构函数:清理队列中的所有成员,唤醒所有阻塞中的生产者、消费者线程。2、生产者线程应该调用的函数。原创 2022-12-25 15:39:56 · 3429 阅读 · 2 评论 -
基于最小堆实现的定时器(HeapTimer)
将所有定时任务中超时时间最小(最快到期)的一个定时任务的超时值作为心搏间隔,这样一旦下一次调用心搏函数时,tick()函数被调用,此时这个超时时间最小的定时任务必然到期,就在tick()函数中处理这个超时任务。,std::swap(i, j)默认采用深拷贝,所以如果交换的两个数据结构内含有指针成员,应该自己定制swap函数,交换指针即可,无需进行默认的深拷贝动作。本文实现了一个基于最小堆的定时器,插入O(logn)、删除O(1)、查找O(1),效率较高。原创 2022-12-25 16:38:14 · 1164 阅读 · 4 评论 -
缓冲区Buffer类的设计(参考Muduo实现)
Buffer的功能需求:Buffer类的设计目的是再创造一层应用层缓冲区。其对外表现为一块连续的内存(char* p, int len),以方便客户代码的编写。size() 可以自动增长,以适应不同大小。内部以 std::vector来保存数据,并提供相应的访问函数。,一个 std::vector,和两个size_t的readerIndex,writerIndex用来表示读写的位置。此外,buffer类应模仿平时使用的容器,提供访问数据元素的这里提供。原创 2022-12-29 22:52:55 · 1252 阅读 · 7 评论