利用Epoll实现Web服务器(黑马Linux网络编程项目)

Epoll实现Web服务器

项目概述:

  本项目主要是对黑马linux网络编程中的Web服务器进行复现以及总结,项目主要功能是 在本地运行服务器代码后,利用浏览器可以访问服务器上的文件.项目结果如下图所示:
浏览器读取目录浏览器读取单个图片

代码流程图

在这里插入图片描述
  在main函数中,首先是对输入参数格式进行判断, 即在执行调用命令的时候,必须加上端口号以及要访问的根目录.接着在主函数中只要是执行epoll-run函数,而epoll run函数也是整个代码的逻辑核心.
  在epoll-run 函数中,首先是创建epoll监听树, 然后调用init-listen-fd函数创建监听节点,并将其挂到监听树上.然后在一个死循环中, 利用epoll-wait函数阻塞监听前面创建的监听树,如果发现有新的节点返回,则需要判断新的节点是监听节点(listenfd), 还是已经挂到监听树上的节点发来数据(cfd).
如果是listenfd,则调用do_accept函数创建用于与浏览器端通信的cfd, 并将其挂到监听树上.
如果是cfd, 则需要解析http协议,取出要访问的文件, 将对应的文件或者目录传回到浏览器端.

主要模块分析

1. init-listen-fd函数

此函数的主要目的是将建立服务器的一些准备工作封装到一起,具体为
(1)利用socket函数 创建监听套接字listenfd
(2)利用bind函数将指定端口绑定到listenfd 上
(3)利用listen 函数设置监听上限
(4)利用epoll_ctl函数将创建好的listenfd 添加到监听树上

2. do_accept 函数

  此函数的主要目的是利用accept 函数创建用于连接浏览器端的cfd, 并且设置epoll 的ET模式(边沿触发,更加高效), 并且设置为非阻塞模型(ET模式必须与非阻塞模式搭配使用), 最后将创建的cfd 添加到监听树上.

3. do_read函数(整个项目最核心的部分)

  此函数的主要目的是根据cfd,解析http协议的请求行, 获取要访问的文件或者目录的路径, 并且将响应的http协议(包括状态行以及要访问的数据)发送回浏览器页面.

  在解析http协议的请求行中,利用了sscanf函数以及正则表达式去匹配请求行的三个部分,其中path 则为要访问的文件或者目录
在这里插入图片描述

sscanf(request, "%[^ ] %[^ ] %[^ ]", method, path, protocol);

  在得到要访问的文件名以后,利用stat函数获取文件的属性(目录or文件),如果要访问的文件不存在,则会返回一个404错误页面
在这里插入图片描述
  如果是单个文件, 则需要先发送请求行,再利用send_file 函数按行读取文件,并将其发送会浏览器端, 其中除了请求行, 比较重要的是文件类型(在本项目中利用get_file_type 函数获取), 还有文件大小, 可以传-1让内核自己去计算,也可以传实际的大小,但是大小如果出错,则会造成数据丢失.
在这里插入图片描述

  如果是目录, 也需要先传协议头部分,但是值得说明的是,在显示目录的时候,整个数据是封装在一个html页面里面的, 而且显示每个目录项,也都采用超链接的方式.
  在send_dir 函数内部, 首先利用scandir 函数遍历目录, 此函数返回一个数组, 数组中的每一位都是一个目录项, 所以直接遍历数组即可访问目录, 在遍历每一个目录项的时候, 也需要判断目录项的属性, 如果是文件, 则直接将其包含在超链接里面即可, 如果目录项还是一个目录, 则需要对目录项的名字进行拼接, 包含在超链接里面, 以便下一次访问子目录的内容, 具体html语言格式在此不再展开.

总结:

  这是一个web 服务器入门的项目,代码也不是很多, 但是通过复现一遍所有代码, 收获还是蛮大的, 算是懂得了后台服务器编程的基本思路, 以后还要在上面继续扩展.

源码:

链接.

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值