注册 | 登录读书好,好读书,读好书!
读书网-DuShu.com
当前位置: 首页出版图书科学技术计算机/网络软件与程序设计C++服务器开发精髓

C++服务器开发精髓

C++服务器开发精髓

定 价:¥168.00

作 者: 张远龙 著
出版社: 电子工业出版社
丛编项:
标 签: 暂缺

购买这本书可以去


ISBN: 9787121412639 出版时间: 2021-07-01 包装: 平装
开本: 16开 页数: 字数:  

内容简介

  本书从操作系统原理角度讲解进行C++服务器开发所需掌握的技术栈。全书总计9章,第1~2章讲解C++ 11/14/17新标准中的常用特性、新增类库,以及C++开发者必须熟练掌握的开发调试工具链;第3~6章详细讲解C++服务器开发中的多线程编程技术、网络编程重难点知识、网络故障调试与排查常用工具,以及通信协议的设计思路、技巧;第7~8章详细讲解一个带网络通信组件的高性能服务的基本设计思路和注意事项;第9章进一步补充服务相关的常用模块设计思路和方法。本书秉承的思想是,通过掌握技术原理,可以轻松制造“轮子”,灵活设计出优雅、鲁棒的服务,并快速学习新技术。 无论是对于C/C++开发者、计算机专业的学生,还是对于想了解操作系统原理的读者,本书都极具参考价值。

作者简介

  张远龙,微信公众号“高性能服务器开发”的作者,曾就职于银天下、携程、字节跳动等公司,做过金融交易系统、IM、呼叫中心等项目,研究方向为高性能高并发服务开发。

图书目录

第1章 C++必知必会.. 1
1.1 C++ RAII惯用法... 1
1.1.1 版本1:最初的写法... 1
1.1.2 版本2:使用goto语句... 3
1.1.3 版本3:使用do...while(0)循环... 5
1.1.4 版本4:使用RAII惯用法... 7
1.1.5 小结... 12
1.2 pimpl惯用法... 12
1.3 C++ 11/14/17新增的实用特性... 17
1.4 统一的类成员初始化语法与std::initializer_list. 19 1.5 C++ 17注解标签(attributes)... 24
1.5.1 C++ 98/03的enumeration和C++ 11的enumerator 25
1.5.2 C++ 17的注解标签... 25
1.6 final、override关键字和=default、=delete语法... 28
1.7 auto关键字的用法... 34
1.8 Range-based循环语法... 35
1.8.1 自定义对象如何支持Range-based循环语法... 37
1.8.2 for-each循环的实现原理... 38
1.9 C++ 17结构化绑定... 39
1.10 stl容器新增的实用方法... 43
1.10.1 原位构造与容器的emplace系列函数... 43
1.10.2 std::map的try_emplace方法与insert_or_assign方法... 44
1.11 stl 中的智能指针类详解... 52

第2章 C++后端开发必备的工具和调试知识.. 71
2.1 SSH工具与FTP工具... 71
2.1.1 Xshell 71
2.1.2 FTP. 75
2.2 makefile与CMake. 76
2.3 使用Visual Studio管理和阅读开源项目代码... 83
2.4 gdb调试... 87
2.4.1 被调试的程序需要带调试信息... 87
2.4.2 启动gdb调试的方法... 89
2.5 gdb常用命令详解——利用gdb调试Redis. 94
2.6 使用gdb调试多线程程序... 126
2.6.1 调试多线程程序的方法... 126
2.6.2 在调试时控制线程切换... 128
2.7 使用gdb调试多进程程序——以调试Nginx为例... 137
2.8 gdb实用调试技巧... 143
2.8.1 将print输出的字符串或字符数组完整显示... 144
2.8.2 让被gdb调试的程序接收信号... 144
2.8.3 函数明明存在,添加断点时却无效... 145
2.8.4 调试中的断点... 146
2.8.5 自定义gdb调试命令... 147
2.9 gdb tui——gdb图形化界面... 148
2.9.1 开启gdb TUI模式... 149
2.9.2 gdb TUI模式下的4个窗口... 149
2.9.3 解决tui窗口不自动更新内容的问题... 150
2.9.4 窗口焦点切换... 150
2.10 gdb的升级版——cgdb. 151
2.11 使用VisualGDB调试... 154
2.11.1 使用VisualGDB调试已经运行的程序... 155
2.11.2 使用VisualGDB从头调试程序... 156

第3章 多线程编程与资源同步.. 159
3.1 线程的基本概念及常见问题... 159
3.1.1 主线程退出,支线程也将退出吗... 159
3.1.2 某个线程崩溃,会导致进程退出吗... 160
3.2 线程的基本操作... 160
3.3 惯用法:将C++类对象实例指针作为线程函数的参数... 178
3.4 整型变量的原子操作... 184
3.4.1 为什么给整型变量赋值不是原子操作... 185
3.4.2 Windows平台上对整型变量的原子操作... 186
3.4.3 C++ 11对整型变量原子操作的支持... 187
3.5 Linux线程同步对象... 190
3.5.1 Linux互斥体... 190
3.5.2 Linux信号量... 198
3.5.3 Linux条件变量... 202
3.5.4 Linux读写锁... 208
3.6 Windows线程同步对象... 217
3.6.1 WaitForSingleObject与WaitForMultipleObjects函数... 217
3.6.2 Windows临界区对象... 219
3.6.3 Windows Event对象... 224
3.6.4 Windows Mutex对象... 229
3.6.5 Windows Semaphore对象... 231
3.6.6 Windows读写锁... 235
3.6.7 Windows条件变量... 238
3.6.8 在多进程之间共享线程同步对象... 243
3.7 C++ 11/14/17线程同步对象... 244
3.7.1 std::mutex系列... 244
3.7.2 std::shared_mutex. 248
3.7.3 std::condition_variable. 253
3.8 如何确保创建的线程一定能运行... 256
3.9 多线程使用锁经验总结... 258
3.10 线程局部存储... 262
3.10.1 Windows的线程局部存储... 262
3.10.2 Linux的线程局部存储... 264
3.10.3 C++ 11 的 thread_local 关键字... 267
3.11 C库的非线程安全函数... 268
3.12 线程池与队列系统的设计... 270
3.12.1 线程池的设计原理... 270
3.12.2 环形队列... 275
3.12.3 消息中间件... 275
3.13 纤程(Fiber)与协程(Routine)... 277

第4章 网络编程重难点解析.. 282
4.1 学习网络编程时应该掌握的socket函数... 282
4.1.1 在Linux上查看socket函数的帮助信息... 283
4.1.2 在Windows上查看socket函数的帮助信息... 285
4.2 TCP网络通信的基本流程... 286
4.3 设计跨平台网络通信库时的一些socket函数用法... 290
4.3.1 socket数据类型... 290
4.3.2 在Windows上调用socket函数... 290
4.3.3 关闭socket函数... 291
4.3.4 获取socket函数的错误码... 291
4.3.5 套接字函数的返回值... 293
4.3.6 select函数第1个参数的问题... 293
4.3.7 错误码WSAEWOULDBLOCK和EWOULDBLOCK.. 294
4.4 bind函数重难点分析... 294
4.4.1 对bind函数如何选择绑定地址... 294
4.4.2 bind函数的端口号问题... 295
4.5 select函数的用法和原理... 302
4.5.1 Linux上的select函数... 302
4.5.2 Windows上的select函数... 317
4.6 socket的阻塞模式和非阻塞模式... 318
4.6.1 如何将socket设置为非阻塞模式... 318
4.6.2 send和recv函数在阻塞和非阻塞模式下的表现... 320
4.6.3 非阻塞模式下send和recv函数的返回值总结... 331
4.6.4 阻塞与非阻塞socket的各自适用场景... 333
4.7 发送0字节数据的效果... 333
4.8 connect函数在阻塞和非阻塞模式下的行为... 339
4.9 连接时顺便接收第1组数据... 343
4.10 如何获取当前socket对应的接收缓冲区中的可读数据量... 346
4.11 Linux EINTR错误码... 351
4.12 Linux SIGPIPE信号... 352
4.13 Linux poll 函数的用法... 353
4.14 Linux epoll模型... 361
4.14.1 基本用法... 361
4.14.2 epoll_wait与poll函数的区别... 363
4.14.3 LT 模式和ET 模式... 363
4.14.4 EPOLLONESHOT 选项... 380
4.15 高效的readv和writev函数... 386
4.16 主机字节序和网络字节序... 387
4.16.1 主机字节序... 387
4.16.2 网络字节序... 388
4.16.3 操作系统提供的字节转换函数汇总... 389
4.17 域名解析API介绍... 390

第5章 网络通信故障排查常用命令.. 397
5.1 ifconfig命令... 397
5.2 ping命令... 401
5.3 telnet命令... 402
5.4 netstat命令... 407
5.5 lsof命令... 409
5.6 nc命令... 412
5.7 curl命令... 415
5.8 tcpdump命令... 416

第6章 网络通信协议设计.. 422
6.1 理解TCP. 422
6.2 如何解决粘包问题... 423
6.3 解包与处理... 425
6.4 从struct到TLV.. 430
6.4.1 协议的演化... 430
6.4.2 协议的分类... 434
6.4.3 协议设计工具... 434
6.5 整型数值的压缩... 435
6.6 设计通信协议时的注意事项... 437
6.6.1 字节对齐... 437
6.6.2 显式地指定整型字段的长度... 438
6.6.3 涉及浮点数时要考虑精度问题... 438
6.6.4 大小端问题... 438
6.6.5 协议与自动升级功能
6.7 包分片... 439
6.8 XML与JSON格式的协议... 444
6.9 一个自定义协议示例... 445
6.10 理解HTTP. 460
6.10.1 HTTP格式介绍... 460
6.10.2 GET与POST方法... 461
6.10.3 HTTP chunk编码... 465
6.10.4 HTTP客户端的编码实现... 466
6.10.5 HTTP服务端的实现... 466
6.10.6 HTTP与长连接... 471
6.10.7 libcurl 471
6.10.8 Restful接口与Java Spring MVC.. 477
6.11 SMTP、POP3与邮件客户端... 478
6.12 WebSocket协议... 499
6.12.1 WebSocket协议的握手过程... 500
6.12.2 WebSocket协议的格式... 503
6.12.3 WebSocket协议的压缩格式... 506
6.12.4 WebSocket协议装包与解包示例... 508
6.12.5 解析握手协议... 512

第7章 单个服务的基本结构.. 515
7.1 网络通信组件的效率问题... 515
7.1.1 高效网络通信框架的设计原则... 515
7.1.2 连接的被动关闭与主动关闭... 519
7.1.3 长连接和短连接... 519
7.2 原始的服务器结构... 520
7.3 一个连接对应一个线程模型... 522
7.4 Reactor模式... 523
7.5 one thread one loop思想... 524
7.5.1 one thread one loop程序的基本结构... 524
7.5.2 线程的分工... 525
7.5.3 唤醒机制的实现... 527
7.5.4 handle_other_things方法的实现逻辑... 532
7.5.5 带定时器的程序结构... 533
7.5.6 one thread one loop的效率保障... 534
7.6 收发数据的正确做法... 534
7.6.1 如何收取数据... 534
7.6.2 如何发送数据... 535
7.6.3 不要多个线程同时利用一个socket收(发)数据... 538
7.7 发送、接收缓冲区的设计要点... 538
7.7.1 为什么需要发送缓冲区和接收缓冲区... 539
7.7.2 如何设计发送缓冲区和接收缓冲区... 539
7.7.3 服务端发送数据时对端一直不接收的问题... 543
7.8 网络库的分层设计... 544
7.8.1 网络库设计中的各个层... 544
7.8.2 将Session进一步分层... 550
7.8.3 连接信息与EventLoop/Thread的对应关系... 551
7.9 后端服务中的定时器设计... 551
7.9.1 最简单的定时器... 551
7.9.2 定时器设计的基本思路... 552
7.9.3 定时器逻辑的性能优化... 561
7.9.4 对时间的缓存... 564
7.10 处理业务数据时是否一定要单独开线程... 565
7.11 非侵入式结构与侵入式结构... 570
7.11.1 非侵入式结构... 570
7.11.2 侵入式结构... 571
7.12 带有网络通信模块的服务器的经典结构... 578
7.12.1 为何要将listenfd设置成非阻塞模式... 578
7.12.2 基于one thread one loop结构的经典服务器结构... 584
7.12.3 服务器的性能瓶颈... 586

第8章 Redis网络通信模块源码分析.. 587
8.1 调试Redis环境与准备... 587
8.1.1 Redis源码编译与启动... 587
8.1.2 通信示例与术语约定... 589
8.2 探究redis-server端的网络通信模块... 589
8.3 探究redis-cli端的网络通信模型... 663
8.4 Redis的通信协议格式... 673
8.4.1 请求命令格式... 673
8.4.2 应答命令格式... 674
8.4.3 多命令和流水线... 677
8.4.4 特殊的redis-cli与内联命令... 677
8.4.5 Redis对协议数据的解析逻辑... 678

第9章 服务器开发中的常用模块设计.. 681
9.1 断线自动重连的应用场景和逻辑设计... 681
9.2 保活机制与心跳包... 683
9.2.1 TCP keepalive选项... 683
9.2.2 应用层的心跳包机制设计... 684
9.2.3 有代理的心跳包机制设计... 689
9.2.4 带业务数据的心跳包... 690
9.2.5 心跳包与流量... 690
9.2.6 心跳包与调试... 691
9.2.7 心跳包与日志... 691
9.3 日志模块的设计... 692
9.4 错误码系统的设计... 730
9.4.1 错误码的作用... 730
9.4.2 错误码系统设计实践... 731
9.5 监控端口... 733

本目录推荐