近期Python网络编程与多线程/多进程学习复盘
一、核心知识收获
1. 多线程与多进程编程
- 多线程应用:实现图片下载(
DownloadHanlder
类继承Thread
,重写run
方法处理下载逻辑),利用线程并行处理网络IO任务,提高下载效率。 - 多进程应用:拆分1亿元素大列表进行并行求和(
Process
类创建子进程,Queue
实现进程间数据通信),理解“分而治之”思想在CPU密集型任务中的优势。 - 关键区别:多线程适合IO密集型任务(如网络请求、文件读写),多进程适合CPU密集型任务(如大量计算);进程间需通过
Queue
等工具通信,线程可共享内存但需注意锁(threading.Lock
)的使用。
2. TCP网络编程
- 服务器端开发:
- 套接字(
socket
)创建:指定AF_INET
(IPv4)和SOCK_STREAM
(TCP),通过bind
绑定IP与端口、listen
监听连接、accept
阻塞等待客户端连接。 - 多线程处理客户端:每个客户端连接对应一个线程(如
FileTransferHandler
),避免单线程阻塞,支持多客户端同时访问。 - 数据传输:需将数据编码为字节流(
encode('utf-8')
),二进制文件(如图片)需通过base64
编码转为文本格式,结合JSON实现结构化数据传输。
- 套接字(
- 客户端连接:
- 工具连接:掌握CMD/PowerShell中通过
Telnet
(需启用Windows功能)、PowerShell原生命令(New-Object System.Net.Sockets.TCPClient
)连接服务器的方法。 - 自定义客户端:用
socket
的connect
方法连接服务器,recv
接收数据,实现与服务器的交互。
- 工具连接:掌握CMD/PowerShell中通过
3. 数据处理与常见模块
- 列表操作:理解列表切片(
list[start:end]
)的“左闭右开”原则,用于多进程数据分片;认识到大列表(如1亿元素)创建的内存占用问题,学会用range
(按需生成元素)优化。 - 模块使用:
requests
:发送HTTP请求获取API数据(如美女图片API、体重秤接口),解析JSON响应(resp.json()
)。json
:dumps
将字典转为JSON字符串(用于网络传输),loads
解析JSON字符串。base64
:b64encode
/b64decode
实现二进制数据与文本的转换,解决JSON无法传输二进制的问题。time
/datetime
:time()
计算程序执行时间,datetime.now()
获取当前时间用于服务器数据返回。
二、典型疑问与解决方案
疑问类型 | 具体问题 | 解决方案 |
---|---|---|
函数/方法参数问题 | 1. task_handler() 缺少curr_list 和result_queue 参数2. socket.bind() 参数错误 |
1. 调用时传入所有必需参数,多进程中通过args 传递元组参数2. bind 需传入(IP, 端口) 格式的元组 |
数据结构错误 | 1. KeyError: 'newslist' (API返回无该字段)2. TypeError: string indices must be integers |
1. 打印API完整返回数据,确认字段名;检查APIKey有效性 2. 确认循环变量类型(如是否为字典),修正索引方式 |
网络连接问题 | 1. WinError 10049 (绑定无效IP)2. telnet /nc 命令不可用 |
1. 绑定0.0.0.0 (所有可用IP)或本机真实IP(ipconfig 查看)2. 启用Telnet客户端,或用PowerShell原生命令连接 |
多线程/进程逻辑问题 | 1. 计时不准确(漏算数据准备时间) 2. 进程间数据共享失败 |
1. 将start = time() 移到程序最开始,统计全程耗时2. 用 multiprocessing.Queue 实现进程间数据传递 |
三、易错点与改进方向
1. 高频易错点
- 参数格式:忽略
bind
的元组参数格式、args
的元组传递(如少加逗号)、函数调用时参数数量不匹配。 - 数据类型判断:未提前打印API返回数据结构,想当然使用字段名;混淆字符串与字典的索引方式。
- 资源释放与效率:多进程/线程未正确关闭连接(如
client.close()
);大列表重复创建导致内存浪费,未用range
优化。 - 环境配置:忽略Windows系统默认未启用Telnet,直接使用
telnet
命令导致报错。
2. 后续改进方向
- 代码健壮性:增加异常处理(如
try-except
捕获网络请求错误、文件读写错误),避免程序崩溃。 - 性能优化:
- 多线程下载时设置线程池(
concurrent.futures.ThreadPoolExecutor
),避免创建过多线程。 - 大文件传输时拆分数据(如分块发送),避免单次发送数据过大导致阻塞。
- 多线程下载时设置线程池(
- 功能扩展:基于现有TCP服务器,实现客户端向服务器上传文件、服务器对客户端身份验证等功能,深化网络编程理解。
- 调试能力:遇到问题时先打印关键数据(如变量类型、API返回、IP/端口配置),逐步定位问题,减少盲目修改代码。