当前位置: 首页 > news >正文

WebServer04

我们先学习一下epoll:

select/poll/epoll - 知乎

接下来调整一下学习策略。这么多行代码,一行行去读、搞懂每个api如何调用也不现实,而且只读代码对能力的提升还是不如动手实操。接下来打算自己实现一个简单的回声服务器,接着融入多线程、I/O多路复用,理解了之后再回头看WebServer

许久没有打开项目了,中途配置cs144的lab环境,出现了一点问题:VSCode竟然不认识如cassert等库,连std都不认识了!写了一个简单的测试代码,虽然VSCode报错,但是可以正常编译并运行。看起来是VSCode的问题。

先禁用官方的C/C++扩展,使用clangd. 由于项目有makefile,所以直接用bear工具(生成编译数据库)

sudo apt update
sudo apt install bear
cd ~/项目
​
#清理旧编译文件
make clean
​
bear -- make #用bear生成compile_commands.json文件

Ctrl+Shift+P,找到Clangd:Restart Language Server,点击

但还是不行。我们检查一下compile_commands.json:

[{"arguments": ["/usr/bin/g++","-c","-g","-o","server","main.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/main.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-o","server","timer/lst_timer.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/timer/lst_timer.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-o","server","http/http_conn.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/http/http_conn.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-o","server","log/log.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/log/log.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-o","server","CGImysql/sql_connection_pool.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/CGImysql/sql_connection_pool.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-o","server","webserver.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/webserver.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-o","server","config.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/config.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"}
]

可以看到在文件中我们没有指定C++标准,也没有包含系统标准库头文件路径

更改如下:(JSON是不能有注释的,这里只是为了说明)

[{"arguments": ["/usr/bin/g++","-c","-g","-std=c++11",  //添加C++11标准"-I/usr/include/c++/11",  //系统标准库路径"-I/usr/include/x86_64-linux-gnu/c++/11",  //架构相关标准库路径"-I/usr/include",  //系统默认头文件路径"-o","server","main.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/main.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-std=c++11","-I/usr/include/c++/11","-I/usr/include/x86_64-linux-gnu/c++/11","-I/usr/include","-o","server","timer/lst_timer.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/timer/lst_timer.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-std=c++11","-I/usr/include/c++/11","-I/usr/include/x86_64-linux-gnu/c++/11","-I/usr/include","-o","server","http/http_conn.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/http/http_conn.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-std=c++11","-I/usr/include/c++/11","-I/usr/include/x86_64-linux-gnu/c++/11","-I/usr/include","-o","server","log/log.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/log/log.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-std=c++11","-I/usr/include/c++/11","-I/usr/include/x86_64-linux-gnu/c++/11","-I/usr/include","-o","server","CGImysql/sql_connection_pool.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/CGImysql/sql_connection_pool.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-std=c++11","-I/usr/include/c++/11","-I/usr/include/x86_64-linux-gnu/c++/11","-I/usr/include","-o","server","webserver.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/webserver.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"},{"arguments": ["/usr/bin/g++","-c","-g","-std=c++11","-I/usr/include/c++/11","-I/usr/include/x86_64-linux-gnu/c++/11","-I/usr/include","-o","server","config.cpp"],"directory": "/home/kevin/cpp-projects/TinyWebServer","file": "/home/kevin/cpp-projects/TinyWebServer/config.cpp","output": "/home/kevin/cpp-projects/TinyWebServer/server"}
]

-std=c++11告诉clangd用c++11标准解析代码

-I明确告诉clangd系统标准库头文件的位置

在其它项目中是否需要构建这个compile_commands.json文件?需要,因为clangd的功能完全依赖它提供的编译上下文。如果项目用的是MakeFile,那么通常使用bear工具,就和前文一样:

make clean
bear -- make

对于更大型的项目,一般都是使用CMake

所以CMake和MakeFile究竟是什么?它们都是构建工具,核心作用是帮我们自动化管理C/C++项目的编译流程。例如一个项目有100个文件,你每次修改都要编译100个文件太麻烦了。而且不同的人可能使用不同的编译选项。构建工具解决的就是这几个问题:自动化、增量编译(只编译修改的文件)、统一配置。

makefile:

#1.定义变量:编译选项、目标文件名、源文件
CXX = g++                #用g++编译
CXXFLAGS = -std=c++11 -Wall  #编译选项:C++11 标准、开启警告
TARGET = myapp           #最终生成的可执行文件名
SRC = main.cpp tool.cpp  #所有源文件
​
#2.生成目标文件
$(TARGET): $(SRC)        #myapp依赖于 main.cpp 和 tool.cpp$(CXX) $(CXXFLAGS) $(SRC) -o $(TARGET)  #实际执行的编译命令(注意开头必须是Tab缩进)
​
# 3.清理编译产物
clean:rm -f $(TARGET) *.o  #执行make clean时,删除可执行文件和中间文件
make        #自动执行编译命令,生成myapp
make clean  #清理编译产物(重新编译前用)

可见Makefile是比较简单的,实际上就是写命令+定义依赖。如果我们只修改了main.cpp,那么它只会编译main.cpp,再和tool.o链接。但是它的缺点也比较明显:需要手写规则(新增一个.cpp文件就要添加到SRC变量中),此外Windows系统下需要MinGW等工具支持。

而CMake则是更加高级的构建工具。它不直接编译代码,而是帮你自动生成Makefile(或者VisualStudio工程、XCode工程等)。CMake允许我们用跨平台的语法写一个CMakeLists.txt(必须要是这个名字),然后自动生成对应平台的构建文件。它的核心优势在于:跨平台(同一个CMakeLists.txt,在Linux生成Makefile,在Mac OS生成XCode工程,在Windows生成VisualStudio工程)、简化配置(自动找源文件、自动处理依赖)、支持复杂项目(处理多目录、动态/静态库、第三方依赖)

补充说一下动态库和静态库:

比喻:你发现你的一道错题涉及某个定理。静态库就是你把这个定理抄在题目旁边,动态库就是你在旁边批注“见课本第80页定理”。前者:你写的会多一点,但你看试卷复习的时候就不需要翻阅课本了。后者:你写的少一点,但看试卷复习的时候就需要课本了。

先回忆 C/C++ 程序的编译流程:源代码(.cpp)-> 编译(生成 .o 目标文件 -> 链接(合并 .o 文件+库文件)-> 可执行文件

静态库和动态库的核心区别在链接阶段:

静态库后缀名:Linux 下是 .a(archive),Windows 下是 .lib

链接过程:编译器会把静态库中你用到的代码段、函数直接复制到你的 .o 文件中,最终合并成一个独立的可执行文件

运行时:可执行文件不依赖任何外部库,直接运行,因为需要的代码都在自己体内

例:你用静态库 liblog.a(日志工具包),链接后生成 webserver 可执行文件 ——webserver 里已经包含了日志功能的代码,即使删除 liblog.awebserver 依然能正常打印日志。

动态库后缀名:Linux 下是 .so(shared object),Windows 下是 .dll(dynamic link library)

链接过程:编译器不会复制库的代码,只会在你的可执行文件中记录 “我需要用到 xxx 动态库的 xxx 函数”,相当于留了一个引用地址

运行时:可执行文件启动后,系统会先查找对应的动态库(比如 /usr/lib/liblog.so),加载到内存中,然后通过引用地址调用库中的函数。如果找不到动态库,程序会直接报错退出,比如 Linux 下的 error while loading shared libraries: liblog.so: cannot open shared object file

例:你用动态库 liblog.so,链接后生成 webserver——webserver 体积很小,但运行时必须依赖 liblog.so 存在于系统中;如果 liblog.so 被更新,比如修复了一个 bug,你不用重新编译 webserver,下次运行时会自动使用新的库

http://www.dtcms.com/a/596457.html

相关文章:

  • 品牌网站建设技术网站搜索引擎优化诊断
  • 优秀企业网站设计WordPress评论楼层
  • 卡索(CASO)汽车调查:新能源时代如何精准度量用户体验?
  • 手动模拟Spring(简易版)
  • 蓝牙钥匙 第88次 蓝牙钥匙未来发展趋势篇:用户体验未来趋势深度解析
  • jmeter集群压测配置方法和注意事项
  • [笔记]SolidWorks转URDF 在rviz2中显示
  • 抖音商城店铺用户体验优化研究(开题报告)
  • 北京网站推广公司排名永久免费的cms系统带商城
  • STM32外设学习--USART串口协议--学习笔记。
  • 汉狮做网站公司郑州苏州建设网站的网络公司
  • 【C#-sqlSugar-sqlite】在Windows从源码编译构建System.Data.SQLite.dll的方法
  • 【WPF】WrapPanel的用法
  • wpf 控件中Margin属性如何设置绑定?
  • 【管综】考研199管理类联考真题试卷及答案解析PDF电子版(2009-2025年)
  • UDP/TCP接收/转发/广播服务端
  • WPF 获取鼠标相对于控件的坐标信息,控制控件锚点放缩
  • 面试题—linux
  • 福田皇岗社区做网站网页制作怎么收费
  • 236. Java 集合 - 使用索引访问 List 元素
  • 天河网站建设哪家强华为企业邮箱
  • 基于Java的电影管理系统的设计与实现
  • C#初级面试题5、拆箱和装箱
  • 如何判断企业是否需要 IAM ?数字化转型中的权限治理自测
  • CSP-J教程——第一阶段——第六课:程序流程控制 - 循环结构(一)for循环
  • 【C++基础与提高】第二章:C++数据类型系统——构建程序的基础砖石
  • 【每天一个知识点】CAG:Context-Augmented Generation
  • 《Linux系统编程之系统导论》【冯诺依曼体系结构 + 操作系统基本概述】
  • 第23天python内容
  • 5.2、Python-字符串的编码和解码