项目地址:OrbitZore/HNUSTnet
因为湖科大的校园网存在莫名其妙的失去登录状态的问题,于是想写个项目解决。🤔
加上最近读《Effective C++》,想要考验一下自己的C++水平。于是就决定用C++实现。👏
粗略想了下技术栈。因为想体验一下跨平台,于是就上了cmake
编译,附带使用boost::asio
作为跨平台网络库。这样一个大体的框架就被敲定了,剩下就是艰难的实现过程了。
但在实现的过程中遇到了麻烦的编码问题。想要代码跨平台,字符常量最好使用UTF-8编码(代码内使用u8""声明一个字符串常量)。但是TCP上的HTTP传输内容编码为GB2312。考虑再三。舍弃掉代码内字符串分开编码的方案,使用Iconv
这一C库将GB2312转换为UTF-8。
CMake
CMakeLists.txt
在命令行中运行cmake <DIR>
,cmake
会检查目录下的CMakeLists.txt
。并解释执行CMakeLists.txt
内容。
声明项目名
project (<Project Name>)
包含子项目
add_subdirectory (<DIR>)
CMake会寻找目录下CMakeLists.txt
,类似调用函数一样的调用解释执行此CMakeLists.txt
。
在项目中引入外部库
寻找外部库
库名一律首字母大写其他小写
find_package(<name>)
适用于一些C库Threads
,Iconv
等
Boost
依赖Threads
find_package(<name> COMPONENTS <lib1> [lib2 ...])
像Boost
这种包含很多子库的大库来说,为了避免引入不必要的库使编译缓慢。在寻找时指出子库成为了一个好选择。
本项目寻找Boost::system
以解决Boost::Asio
依赖问题
适用于一些大型C++库
find_path(BOOST_ASIO_INCLUDE_DIRS "boost/asio.hpp")
本项目会用到Boost.Asio
,其为Headers Only
类型的库。引入时只需Include头文件就行。这个语句作用为寻找Asio的头文件boost/asio.hpp
,并将其目录赋值给BOOST_ASIO_INCLUDE_DIRS变量
find_package
会在一些目录中寻找<name>.cmake
的文件(其实还有找很多其他文件,因不在本项目内所以略过,可参考Cmake之深入理解find_package()的用法),其包含了寻找<name>
这个库并引入到cmake的步骤。一般会初始化<name>_INCLUDE_DIRS
、<name>_LIBRARY_DIRS
和<name>_FOUND
这三个常量。含义分别为这个库的头文件目录,*.obj
目录,库是否找到了。
某些<name>.cmake
会检查一些关于需要引用库的设置变量。本项目即用到了Boost_USE_STATIC_LIBS
等,均可在下文介绍的文档中查询。
CMake中已经包含了一些热门库的<name>.cmake
文件,本项目中所有库均为如此。官方文档地址cmake-modules(7) — CMake 3.19.1 Documentation。
引入头文件
以下做法将会把头文件引入所有子项目。因本项目仅包含一个子项目所以此法可行。如多个子项目可使用target_
系列函数。
include_directories(<DIRS1> [DIRS2 ...])
引入*.obj
文件
以下做法将会把*.obj
文件引入所有子项目。因本项目仅包含一个子项目所以此法可行。如多个子项目可使用target_
系列函数。
link_libraries([item1 [item2 [...]]]
[[debug|optimized|general] <item>] ...)
添加源代码和头文件至项目
add_executable (HNUSTnet <sources1> [sources2])
项目源代码文件说明
源代码文件名 | 说明 |
---|---|
misc.cpp | 提供一些工具函数 |
iconv.hpp | 提供Iconv的C++封装 by Yuya Unno |
TCPclient.cpp | 基于Boost::Asio抽象TCP连接 |
HTTPclient.cpp | 基于TCPclient.cpp提供简单的HTTP封装,并使用iconv.hpp转码 |
HNUSTnet.cpp | 基于HTTPclient.cpp提供login.hnust.cn的API封装,并提供自动连接操作 |
main.cpp | 命令行程序化HNUSTnet.cpp |
依赖库相关资料
u1s1这官方文档比CPP reference难读多了..
介绍Asio的简单使用
Boost的各个子库