如何做网站联盟营销,软件开发兼职平台有哪些,网站开发程序员工资,郑州网站建设搭建公司终于是写完了#xff0c;花费了2周时间#xff0c;一点一点看#xff0c;还没有扩展#xff0c;但是基本功能是已经实现了。利用的是Tcp为网络链接#xff0c;在其上面又写了http的壳。没有使用epoll#xff0c;多路转接难度比较高#xff0c;以后有机会再写#xff0c…终于是写完了花费了2周时间一点一点看还没有扩展但是基本功能是已经实现了。利用的是Tcp为网络链接在其上面又写了http的壳。没有使用epoll多路转接难度比较高以后有机会再写使用了多线程来对每一个链接请求做工作每次处理一个工作后响应结束后服务器主动关闭对端链接做到短链接防止服务器链接过载宕机主要是我的云服务器是学习用的硬件就摆在哪里过多的链接会导致我服务器崩溃这是没有办法的呀。
项目我采用技术有
线程池定向对象池TCP/IPHTTP协议解析生产消费者模型(线程池基于我们的方便)CGI模式C语言对数据库访问其他杂七杂八的知识
设计的类有
object类定向对象内存池创建和析构对象的用户内存池Sock类对listen初始化和获取外部链接的一个插件类为TcpServer做配件。TcpServer类对于链接的承上启下的使用哈希桶在用户层管理每个链接的链接状态为http提供接口使用Sock类的接口。Connection类对从Accept取得的外部链接做进一步封装。 HttpServer类使用TcpServer类做的上层管理。也其实是中转站。 Log类写日志的类。 HttpRequest类管理链接发来的数据解析协议后存放类。 HttpResponse类管理给对端发送的数据保存协议生成的类。 EndPoint类处理协议的地方并且并且构建响应发送http响应报文 CallBack类这是我们处理任务的地方当任务结束析构该类也会析构该链接。 Task类构建对象传递到任务队列中不论阻塞还是环形 GuardLock类哨兵锁我们定义了一个全局的锁为了单例所使用 ThreadPool类线程池一次性启动一堆线程循环的方式等待任务队列有东西有就拿没就等
执行流程大致为
前期我们的服务器启动单例线程池创建多条线程开始等待单例TcpServer生成Connection池生成开始listen套接字绑定开启监听模式accept开始等待链接。浏览器-服务器浏览器构建http报文并且发送给服务器发起链接请求在三次握手后服务器从Sock拿到链接到HttpServer中使用链接创建Task任务对象然后将任务放入连接池中的任务队列后中剩下对接其链接的事情就交给子线程了。然后放入后就继续等待链接了。线程-协议解析在等待的线程从任务队列中得到了一个任务使用任务的回调方法其实就是Callback的’()‘重载每个任务其实都一样都是调用运算符重载只是传入的链接不同。CallBack的运算符重载函数中生成EndPoint对象传入conn链接EndPoint对象启动对链接的读取协议解析构建响应发送响应。构建响应在构建响应的过程中我们甄别是否为CGI模式请求根据GET url是否有参数看看有没有?字符存在如果是POST模式我们直接认为是CGI模式的请求。
非CGI模式打开其url访问的路径文件不用读取其路径文件(在我们的磁盘上)然后其实就发送响应了,然后继续响应报文其他部分。CGI模式创建2个管道做数据的交互创建子进程在程序替换前将子进程的0、1文件描述符dup为管道的读写端文件描述符如果是GET方法的CGI模式我们采用环境变量传参传递快缺点参数不能太长如果是POST则只能读取数据然后子进程程序替换当然在替换前我们还得传个环境变量其是来帮助我们确定请求方法的为了POST方法读取参数使用。在CGI程序中处理完毕后构建响应数据通过dup后的文件描述符1写回父进程然后关闭父进程是使用响应报文的body来接收子进程发送给其的处理后的数据。其他构建构建协议状态行这是同一的构建然后根据状态码构建协议报头head。
响应发送响应构建完毕将响应报文以状态行报头空行实际数据依次发送在发送最后的数据body的时候根据是否为CGI模式区分发送模式是CGI模式就发送响应中保存的body数据不是CGI模式就通过sendfile函数将_fd磁盘中数据直接发送给sock链接中以内核数据拷贝到内核数据的方式减少拷贝body数据不在经过用户层。发送完毕发送完毕EndPoint对象释放当然也可以为其创建对象池。线程结束任务继续尝试从任务池获取下一个任务。服务器-浏览器浏览器得到响应解析协议这不是我该处理的活。