Linux C++项目推荐:文件服务器+如何快速上手C++大项目

1 本次分享的意义

源码地址:https://github.com/shangguanyongshi/WebFileServer.git

视频讲解:Linux C++项目推荐:WebFileServer文件服务器+如何快速上手C++大项目

学完C++和Linux编程后, 可以以WebFileServer文件服务器作为练手项目,比WebServer项目多了文件上传的功能,更加有意义。

这次分享不单只是讲解这个WebFileServer项目如何运行,也能让大家掌握如何快速掌握自己不熟悉的C++项目。

2 项目功能

Web 文件服务器,通过浏览器发送 HTTP 请求管理服务器指定文件夹下的所有文件。主要功能包括:

  • 以 HTML 页面形式返回该文件夹下的所有文件
  • 可以选择本地文件上传到服务器
  • 可以对列表中的文件文件执行下载操作
  • 可以删除服务器中的指定文件

3 整体框架

  • 使用 Reactor 事件处理模型,通过统一事件源,主线程使用 epoll 监听所有的事件,工作线程负责执行事件的逻辑处理
  • 预先创建线程池,当有事件发生时,加入线程池的工作队列中,使用随机选择算法选择线程池中的一个线程处理工作队列的事件
  • 使用 HTTP GET 方法获取文件列表,发起下载文件、删除文件的请求。使用 POST 方法向服务器上传文件
  • 服务端使用有限状态机对请求消息进行解析,根据解析结果执行操作后,向客户端发送页面、发送文件或发送重定向报文
  • 服务端使用 sendfile 函数实现零拷贝数据发送

4 编译和运行

  1. build 项目
sh ./build.sh

默认的编译不支持调试,可以修改makefile增加-g编译选项。

然后再重新编译,以方便调试代码。

  1. 启动文件服务器
./main
  1. 在浏览器端输入 服务端ip:端口号(端口号默认是8888)
serverip:8888

5 如何快速分析代码

5.1 main函数入口

(gdb) b main
Breakpoint 1 at 0x5555555590ad: file main.cpp, line 3.

5.2 分析网络模型

通过info threads可以看到 共有五个线程,其中主线程是调用了epoll,再加上README的讲解可以推断出来这个项目是单个epoll +线程池的模式

* 1    Thread 0x7ffff79a9740 (LWP 339328) "main" 0x00007ffff7c1c68e in epoll_wait (epfd=4, events=0x7fffffffaf14, maxevents=1024, timeout=-1) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
  2    Thread 0x7ffff79a8700 (LWP 339343) "main" futex_abstimed_wait_cancelable ( ) at ../sysdeps/nptl/futex-internal.h:320
  3    Thread 0x7ffff71a7700 (LWP 339344) "main" futex_abstimed_wait_cancelable ( ) at ../sysdeps/nptl/futex-internal.h:320
  4    Thread 0x7ffff69a6700 (LWP 339345) "main" futex_abstimed_wait_cancelable ( ) at ../sysdeps/nptl/futex-internal.h:320
  5    Thread 0x7ffff61a5700 (LWP 339346) "main" futex_abstimed_wait_cancelable ( ) at ../sysdeps/nptl/futex-internal.h:320

5.3 网络数据收发

5.3.1 数据接收

断点 recv

Thread 4 "main" hit Breakpoint 4, __libc_recv (fd=5, buf=0x7ffff69a5600, len=2048, flags=0) at ../sysdeps/unix/sysv/linux/recv.c:24
24      ../sysdeps/unix/sysv/linux/recv.c: No such file or directory.
(gdb) bt
#0  __libc_recv (fd=5, buf=0x7ffff69a5600, len=2048, flags=0) at ../sysdeps/unix/sysv/linux/recv.c:24
#1  0x000055555555df4a in HandleRecv::process (this=0x55555558bb90) at event/myevent.cpp:38
#2  0x000055555555c114 in ThreadPool::run (this=0x55555558b2b0) at threadpool/threadpool.cpp:114
#3  0x000055555555bc5c in ThreadPool::worker (arg=0x55555558b2b0) at threadpool/threadpool.cpp:77
#4  0x00007ffff7f8a609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#5  0x00007ffff7c1c353 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

很明显,这个项目是在线程池的线程里读取socket 数据并解析解析处理。

5.3.2 数据发送

断点 send

说明数据的响应也是在线程池的线程进行的。

6 拓展建议

建议将本项目的功能一直到muduo库进一步测试,对比分析性能的差异。

也建议和nginx做更多测试对比。

这样可以不断优化项目的性能,面试的时候也能有更多可以讲解的内容。

#我的失利项目复盘##校招过来人的经验分享##校招##简历中的项目经历要怎么写##c++#
全部评论
mark一下项目地址
点赞 回复 分享
发布于 05-06 08:45 广东

相关推荐

04-25 15:44
中山大学 C++
某公司一颗钉子:可以看看下面这几个项目 云存储项目:https://www.bilibili.com/video/BV1XPfTY8EGD/ 多线程任务队列系统:https://www.bilibili.com/video/BV1XS9dYsE9d/ RPC项目:https://www.bilibili.com/video/BV15ff4YsEPy/ web多人聊天:https://www.bilibili.com/video/BV1iYtrezEkA/ 仿写redis之Qedis:https://www.bilibili.com/video/BV1a4zzYKEAt/
点赞 评论 收藏
分享
04-18 18:09
已编辑
西北工业大学 C++
从3月19日投递简历到4月18日接到hr电话oc,差一天满一个月,历经腾讯五轮面试的考验,终于走到了目前这一环节。曾在牛客网受益于众多面经分享,如今也将自己面试中遇到的一些需要思考的问题整理出来,希望能为正在面试的牛友们提供一些启发。时间线:3&nbsp;月&nbsp;19&nbsp;日&nbsp;投递简历&nbsp;→&nbsp;同日完成测评4&nbsp;月&nbsp;1&nbsp;日&nbsp;腾讯云一面(未通过)4&nbsp;月&nbsp;7&nbsp;日&nbsp;wxg一面&nbsp;→&nbsp;4&nbsp;月&nbsp;9&nbsp;日&nbsp;二面4&nbsp;月&nbsp;11&nbsp;日&nbsp;电话邀约面委会&nbsp;→&nbsp;4&nbsp;月&nbsp;16&nbsp;日&nbsp;面委会(原计划&nbsp;4&nbsp;月&nbsp;15&nbsp;日推迟)4&nbsp;月&nbsp;18&nbsp;日&nbsp;HR&nbsp;面&nbsp;→&nbsp;当日完成云证流程并接到&nbsp;OC&nbsp;电话问题整理:1.&nbsp;TCP相比于UDP延迟的原因(连接过程、流量控制等方面回答)2.&nbsp;前缀++和后缀++哪个性能更优,应用在哪些场景(这个问题有个大坑,不能直接说用前缀++来遍历)3.&nbsp;发生哈希冲突时有什么解决方法?拉链法可能导致哈希值相同的结点挂起来导致查询效率变慢,如何解决?(拉链法冲突节点在8以上时转为红黑树,降到6时恢复链表)4.&nbsp;哈希表什么时候进行扩容?(负载因子?)5.&nbsp;粘包/拆包有哪些处理方式,除TLV外还有什么方式?6.&nbsp;什么情况下的粘包不需要处理?二进制数据可通过\0,\n进行粘包处理吗?7.&nbsp;如何查看某个端口有没有被占用(nmap或者telnet)8.&nbsp;HTTP字段介绍9.&nbsp;delete&nbsp;this&nbsp;合法吗10.&nbsp;对称加密/非对称加密/哈希算法分别是什么?有什么用?有哪些常用算法?11.&nbsp;C++有很多long类型的变量,如何求他们的平均值,注意要防备数值溢出(感觉算是数学题,使用average&nbsp;+=&nbsp;(numbers[i]&nbsp;-&nbsp;average)&nbsp;/&nbsp;(i&nbsp;+&nbsp;1)边累加边计算平均值)12.&nbsp;C++函数调用过程,三种函数传参的区别13.&nbsp;c++特性发展历程(每个版本更新的特点),&nbsp;以及每个版本主要更新的特性14.&nbsp;1000*1000的彩色图片占多少内存15.&nbsp;协程和线程进程相比有什么区别?它的优势和劣势有哪些?(从内存占用、上下文切换、不需进行额外同步操作、处处非阻塞、本质是单线程)16.&nbsp;有了http为什么还需要websocket17.&nbsp;TCP中超时重传时间是如何计算的?(有公式)18.&nbsp;梯子为什么可以让我们跳过防火墙?19.&nbsp;内存泄漏在哪些情况下发生?(new/delete、智能指针互引用、基类析构未虚)如何处理?(valgrind或者通过函数记录内存分配和释放的次数)20.&nbsp;QT可以跨平台吗,原理是什么?槽函数?(抽象类)21.&nbsp;死锁是什么?活锁是什么?死锁和活锁如何处理?如何检测?22.&nbsp;进程在Linux里调度用了什么算法?(CFS)23.&nbsp;浏览器的每个标签页是一个线程还是一个进程,为什么是进程,还有没有其他方面能体现进程之间隔离性的优点?24.&nbsp;python装饰器25.&nbsp;linux下进程和线程的调度有区别吗(都是一个实体)26.&nbsp;docker底层是如何隔离的(namespace)27.&nbsp;守护进程如何建立(fork)28.&nbsp;客户端time_wait过多怎么办29.&nbsp;为什么每个操作系统都有进程、线程?(从进程和线程的特性来说)30.&nbsp;用户鉴权,详细说一下JWT31.&nbsp;集群裂脑、惊群效应32.&nbsp;零拷贝33.&nbsp;说一下无锁如何实现,内存模型有哪些编程题的话目前感觉有难度是让手写一个线程池,包含单例、模板、线程安全、完美转发、生产者消费者、原子操作、互斥锁这些要素。上面这些是面试过程中,我遇到了会思考一下的问题,其他的问题都很基础就没记录。希望能帮到大家。
点赞 评论 收藏
分享
评论
点赞
2
分享

创作者周榜

更多
牛客网
牛客企业服务