新書推薦:
《
成吉思汗传:看历代帝王将相谋略 修炼安身成事之根本
》
售價:HK$
61.6
《
爱丁堡古罗马史-罗马城的起源和共和国的崛起
》
售價:HK$
76.8
《
自伤自恋的精神分析
》
售價:HK$
52.8
《
大宋悬疑录:貔貅刑
》
售價:HK$
74.8
《
不被大风吹倒
》
售價:HK$
65.9
《
人生解忧:佛学入门四十讲
》
售價:HK$
107.8
《
东野圭吾:分身(东野圭吾无法再现的双女主之作 奇绝瑰丽、残忍又温情)
》
售價:HK$
64.9
《
浪潮将至
》
售價:HK$
86.9
|
內容簡介: |
本书从操作系统原理角度讲解进行C 服务器开发所需掌握的技术栈。全书总计9章,第1~2章讲解C 11/14/17新标准中的常用特性、新增类库,以及C 开发者必须熟练掌握的开发调试工具链;第3~6章详细讲解C 服务器开发中的多线程编程技术、网络编程重难点知识、网络故障调试与排查常用工具,以及通信协议的设计思路、技巧;第7~8章详细讲解一个带网络通信组件的高性能服务的基本设计思路和注意事项;第9章进一步补充服务相关的常用模块设计思路和方法。本书秉承的思想是,通过掌握技术原理,可以轻松制造“轮子”,灵活设计出优雅、鲁棒的服务,并快速学习新技术。无论是对于C/C 开发者、计算机专业的学生,还是对于想了解操作系统原理的读者,本书都极具参考价值。
|
關於作者: |
本人有一个千人的技术QQ群,群成员为C 服务器开发相关学习者及同行;另外是技术公众号【高性能服务器开发】的维护者,目前粉丝8000左右。另有CSDN博客、个人站点也可用于宣传。
|
目錄:
|
第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<T> 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.6.1 final关键字 28
1.6.2 override关键字 29
1.6.3 =default语法 31
1.6.4 =delete语法 32
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
1.11.1 C 98/03的尝试——std::auto_ptr 52
1.11.2 std::unique_ptr 55
1.11.3 std::shared_ptr 59
1.11.4 std::enable_shared_from_this 61
1.11.5 std::weak_ptr 63
1.11.6 智能指针对象的大小 67
1.11.7 使用智能指针时的注意事项 68
第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.5.1 gdb常用调试命令概览和说明 94
2.5.2 用gdb调试Redis前的准备工作 96
2.5.3 run命令 97
2.5.4 continue命令 98
2.5.5 break命令 98
2.5.6 tbreak命令 101
2.5.7 backtrace与frame命令 101
2.5.8 info break、enable、disable、delete命令 102
2.5.9 list命令 104
2.5.10 print与ptype命令 107
2.5.11 info与thread命令 109
2.5.12 next、step、until、finish、return、jump命令 112
2.5.13 disassemble命令 122
2.5.14 set args与show args命令 122
2.5.15 watch命令 123
2.5.16 display命令 124
2.5.17 dir命令 125
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.2.1 创建线程 160
3.2.2 获取线程ID 166
3.2.3 等待线程结束 173
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.9.1 减少锁的使用次数 258
3.9.2 明确锁的范围 259
3.9.3 减少锁的使用粒度 259
3.9.4 避免死锁的一些建议 260
3.9.5 避免活锁的一些建议 262
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
3.13.1 纤程 277
3.13.2 协程 280
第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.10.1 分析 346
4.10.2 注意事项 350
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 协议与自动升级功能 438
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.11.1 邮件协议简介 478
6.11.2 SMTP 479
6.11.3 POP3 494
6.11.4 邮件客户端 499
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
|
|