第1章 客户端/服务器网络编程简介 1
1.1 基础:协议栈与库 1
1.2 应用层 4
1.3 协议的使用 5
1.4 一个原始的网络会话 6
1.5 层层深入 8
1.6 编码与解码 9
1.7 网际协议 10
1.8 IP地址 11
1.9 路由 12
1.10 数据包分组 13
1.11 进一步学习IP 14
1.12 小结 15
第2章 UDP 16
2.1 端口号 17
2.2 套接字 18
2.2.1 混杂客户端与垃圾回复 22
2.2.2 不可靠性、退避、阻塞和超时 23
2.2.3 连接UDP套接字 27
2.2.4 请求ID:好主意 28
2.3 绑定接口 29
2.4 UDP分组 31
2.5 套接字选项 33
2.6 广播 33
2.7 小结 35
第3章 TCP 37
3.1 TCP工作原理 37
3.2 何时使用TCP 38
3.3 TCP套接字的含义 39
3.4 一个简单的TCP客户端和服务器 40
3.4.1 每个会话使用一个套接字 43
3.4.2 地址已被占用 44
3.5 绑定接口 46
3.6 死锁 46
3.7 已关闭连接,半开连接 51
3.8 像使用文件一样使用TCP流 52
3.9 小结 53
第4章 套接字名与DNS 54
4.1 主机名与套接字 54
4.1.1 套接字的5个坐标 55
4.1.2 IPv6 56
4.2 现代地址解析 57
4.2.1 使用getaddrinfo()为服务器绑定端口 58
4.2.2 使用getaddrinfo()连接服务 59
4.2.3 使用getaddrinfo()请求规范主机名 60
4.2.4 其他getaddrinfo()标记 61
4.2.5 原始的名称服务程序 62
4.2.6 在代码中使用getsockaddr() 62
4.3 DNS协议 64
4.3.1 为何不使用原始DNS 66
4.3.2 使用Python进行DNS查询 66
4.3.3 解析邮箱域名 68
4.4 小结 70
第5章 网络数据与网络错误 71
5.1 字节与字符串 71
5.1.1 字符串 72
5.1.2 二进制数与网络字节顺序 75
5.2 封帧与引用 77
5.3 pickle与自定义定界符的格式 82
5.4 XML与JSON 83
5.5 压缩 84
5.6 网络异常 85
5.6.1 抛出更具体的异常 87
5.6.2 捕捉与报告网络异常 87
5.7 小结 88
第6章 TLS/SSL 90
6.1 TLS无法保护的信息 90
6.2 可能出问题的地方 91
6.3 生成证书 93
6.4 TLS负载移除 95
6.5 Python 3.4默认上下文 96
6.6 手动选择加密算法与完美前向安全 102
6.7 支持TLS的协议 104
6.8 了解细节 105
6.9 小结 111
第7章 服务器架构 112
7.1 浅谈部署 112
7.2 一个简单的协议 114
7.3 单线程服务器 117
7.4 多线程与多进程服务器 120
7.5 异步服务器 122
7.5.1 回调风格的asyncio 126
7.5.2 协程风格的asyncio 127
7.5.3 遗留模块asyncore 129
7.5.4 两全其美的方法 130
7.6 在inetd下运行 131
7.7 小结 133
第8章 缓存与消息队列 134
8.1 使用Memcached 134
8.2 散列与分区 137
8.3 消息队列 140
8.4 小结 145
第9章 HTTP客户端 147
9.1 Python客户端库 147
9.2 端口、加密与封帧 149
9.3 方法 151
9.4 路径与主机 152
9.5 状态码 152
9.6 缓存与验证 155
9.7 传输编码 157
9.8 内容协商 158
9.9 内容类型 160
9.10 HTTP认证 160
9.11 cookie 162
9.12 连接、Keep-Alive和httplib 163
9.13 小结 164
第10章 HTTP服务器 166
10.1 WSGI 166
10.2 异步服务器与框架 168
10.3 前向代理与反向代理 169
10.4 4种架构 170
10.4.1 在Apache下运行Python 171
10.4.2 纯粹的Python HTTP服务器的兴起 172
10.4.3 反向代理的优势 172
10.5 平台即服务 173
10.6 GET与POST模式和REST的问题 174
10.7 不使用Web框架编写WSGI可调用对象 176
10.8 小结 180
第11章 万维网 181
11.1 超媒体与URL 181
11.1.1 解析与构造URL 182
11.1.2 相对URL 184
11.2 超文本标记语言 186
11.3 读写数据库 189
11.4 一个糟糕的Web应用程序(使用Flask) 190
11.5 表单和HTTP方法 195
11.5.1 表单使用了错误方法的情况 197
11.5.2 安全的cookie与不安全的cookie 198
11.5.3 非持久型跨站脚本 200
11.5.4 持久型跨站脚本 201
11.5.5 跨站请求伪造 202
11.5.6 改进的应用程序 203
11.6 使用Django编写的账单应用程序 205
11.7 选择Web框架 209
11.8 WebSocket 210
11.9 网络抓取 211
11.9.1 获取页面 212
11.9.2 抓取页面 215
11.9.3 递归抓取 217
11.10 小结 221
第12章 电子邮件的构造与解析 222
12.1 电子邮件消息格式 222
12.2 构造电子邮件消息 224
12.3 添加HTML与多媒体 226
12.4 添加内容 231
12.5 解析电子邮件消息 232
12.6 遍历MIME部件 234
12.7 邮件头编码 236
12.8 解析日期 237
12.9 小结 238
第13章 SMTP 239
13.1 电子邮件客户端与Web邮件服务 239
13.1.1 最开始使用命令行发送电子邮件 239
13.1.2 客户端的兴起 240
13.1.3 转移到Web邮件 241
13.2 SMTP的使用方法 243
13.2.1 发送电子邮件 244
13.2.2 邮件头与信封接收者 245
13.2.3 多跳 246
13.3 SMTP库简介 247
13.4 错误处理与会话调试 248
13.5 从EHLO获取信息 251
13.6 使用安全套接层和传输层安全协议 253
13.7 认证的SMTP 255
13.8 关于SMTP的小贴士 257
13.9 小结 257
第14章 POP 258
14.1 POP服务器的兼容性 258
14.2 连接与认证 259
14.3 获取邮箱信息 261
14.4 消息的下载与删除 263
14.5 小结 265
第15章 IMAP 266
15.1 在Python中使用IMAP 267
15.1.1 IMAPClient 269
15.1.2 查看文件夹 271
15.1.3 消息号与UID 272
15.1.4 消息范围 272
15.1.5 摘要信息 272
15.1.6 下载整个邮箱 274
15.1.7 单独下载消息 276
15.1.8 标记并删除消息 281
15.1.9 删除消息 282
15.1.10 搜索 282
15.1.11 操作文件夹与消息 284
15.1.12 异步性 285
15.2 小结 285
第16章 Telnet和SSH 286
16.1 命令行自动化 286
16.1.1 命令行扩展与引用 287
16.1.2 UNIX命令行参数几乎可以包含任意字符 288
16.1.3 对字符进行引用 290
16.1.4 糟糕的Windows命令行 291
16.1.5 终端的特别之处 292
16.1.6 终端的缓冲行为 295
16.2 Telnet 296
16.3 SSH:安全shell 300
16.3.1 SSH概述 300
16.3.2 SSH主机密钥 301
16.3.3 SSH认证 303
16.3.4 shell会话与独立命令 304
16.3.5 SFTP:通过SSH进行文件传输 308
16.3.6 其他特性 310
16.4 小结 311
第17章 FTP 313
17.1 何时不使用FTP 313
17.1.1 通信信道 314
17.1.2 在Python中使用FTP 315
17.1.3 ASCII和二进制文件 316
17.1.4 二进制下载进阶功能介绍 318
17.1.5 上传数据 319
17.1.6 二进制上传进阶功能介绍 320
17.1.7 错误处理 321
17.1.8 目录扫描 322
17.1.9 目录检测以及递归下载 324
17.1.10 目录的创建以及文件和目录的删除 326
17.1.11 安全地操作FTP 326
17.2 小结 326
第18章 RPC 328
18.1 RPC的特性 329
18.1.1 XML-RPC 330
18.1.2 JSON-RPC 336
18.1.3 自文档的数据 339
18.1.4 关于对象:Pyro和RPyC 340
18.1.5 RPyC例子 341
18.1.6 RPC、Web框架和消息队列 343
18.1.7 从网络错误中恢复 344
18.2 小结 344