功能
用线程池来实现的一个并发的web服务器。
项目模块
主要分为三个模块
1,就是对,信号量,互斥锁,条件变量的封装。
2,线程池模块,这是一个模板类,这里使用的模板参数是另外一个模块,就是http模块。
3,http模块封装为一个对象,用来实现对客户端请求报文的读取,解析,以及响应报文的生成和发送。
4,最后一个模块就是main函数模块。
整个项目工作的流程
main函数启动,利用线程池对象先建立一个处理对象是http对象的线程池,每一个线程建立之后运行到信号量的sem_wait函数处等待信号量的值改变。
线程池建立好之后,在main函数中建立套接字并接听,然后使用I/O复用的epoll函数对套接字的事件进行注册和检测。
这里套接字的注册使用了套接字事件处理模式中的ET模式。
接下来使用两种事件处理模式中的reactor模式来实现主线程和线程池中的子线程。
当epoll_wait检测到连接好的套接字有数据可读是,就往线程池的消息队列中注册一个http对象,当成功注册整个http对象之后,信号量的值改变,那么等待信号量的线程继续执行。
这个时候为了防止多个线程同时访问消息队列,在线程访问消息队列之前,先给互斥锁上锁,那么就可以保障只有获取锁的线程才可以从消息队列中http对象,获取http对象之后解锁,然后启动这个http对象,也就是执行这http对象的入口函数,执行对客户端请求报文的读取,解析,和响应报文的生成和发送。
———————————————————————————————————————————
http对象怎么解析请求报文
首先从套接字中读取请求报文信息
然后利用请求报文每一行都是以“回车换行符”结尾的特点,分别获取请求行,消息头和消息体。
解析完请求行之后解析消息头,处理完消息头之后解析消息体。
请求行的解析就是利用strpbrk函数和strspn函数获取请求行中的请求方法,url,HTTP版本。
当解析完请求报文之后,就是根据解析的结果生成HTTP响应报文,然后发送给客户端。
HTTP响应报文怎么生成的
根据文件的获取成功与否,生成不同的响应报文。
更具不同的结果往不同的缓冲区写入数据,然后利用writev函数合并多块缓冲区的数据发送出去。
———————————————————————————————————————————