Python网络编程实战:多线程素数服务与简易爬虫开发
目录
一、实验背景与核心价值
二、多线程TCP素数判定服务
2.1 系统架构设计
2.2 服务端实现详解
关键模块导入
核心功能实现
2.3 客户端实现要点
三、基于Socket的网页爬虫开发
3.1 核心实现流程
3.2 安全连接处理
四、关键技术解析
4.1 TCP粘包问题解决方案
4.2 多线程资源管理
4.3 HTTP协议解析要点
五、性能优化建议
一、实验背景与核心价值
本实验通过两个典型场景展示了Python网络编程的核心能力:使用多线程TCP协议实现高并发素数判定服务,以及基于socket的简易网页爬虫开发。这两个案例分别体现了网络编程中的服务端开发与客户端通信技术,以及HTTP协议的实际应用,是理解现代网络编程范式的绝佳切入点。
二、多线程TCP素数判定服务
2.1 系统架构设计
采用经典的主从式(Master-Slave)架构:
- 服务端:多线程处理客户端连接
- 客户端:短连接模式
- 通信协议:TCP协议保证可靠性
2.2 服务端实现详解
关键模块导入
import socket
from itertools import count
from threading import Thread
import struct
from msvcrt import getwche
核心功能实现
素数计算算法优化:
def getPrimes():
primes = {2, 3, 5}
def isPrime(n):
if n <= 1:
return False
if n in primes:
return True
if n % 6 not in {1, 5}:
return False
sqrt_n = int(n**0.5)
for i in range(3, sqrt_n+1, 2):
if n % i == 0:
return False
primes.add(n)
return True
for num in count(7, 2):
try:
isPrime(num)
except MemoryError:
break
网络通信处理流程:
def receiveNumber():
sock = socket.socket()
sock.bind(('localhost', 5005))
sock.listen(50)
while True:
client, addr = sock.accept()
try:
# 接收数据长度
length = struct.unpack('i', client.recv(4))[0]
# 接收实际数据
data = client.recv(length).decode()
num = int(data)
max_prime = max(primes)
if num > max_prime:
response = "需要计算,结果未知"
else:
response = "是素数" if num in primes else "不是素数"
# 构造响应数据
response_data = response.encode()
header = struct.pack('i', len(response_data))
client.sendall(header + response_data)
except Exception as e:
print(f"处理错误: {e}")
finally:
client.close()
2.3 客户端实现要点
健壮的输入验证:
while True:
data = input("输入数字(q退出): ").strip()
if not data:
continue
if data == 'q':
break
if not data.isdigit():
print("无效输入")
continue
# 网络通信处理...
网络异常处理:
try:
sock = socket.socket()
sock.settimeout(0.5)
sock.connect(('127.0.0.1', 5005))
sock.settimeout(None)
except Exception as e:
print("服务器不存在")
exit(1)
三、基于Socket的网页爬虫开发
3.1 核心实现流程
HTTP请求构造器:
def build_request(host, path):
return f"GET {path} HTTP/1.1\r\n" \
f"Host: {host}\r\n" \
"User-Agent: PythonSocketCrawler/1.0\r\n" \
"Connection: close\r\n\r\n"
响应处理优化:
def process_response(response):
try:
headers, _, body = response.partition('\r\n\r\n')
title_match = re.search(r'<title>(.*?)</title>', body, re.IGNORECASE)
return title_match.group(1) if title_match else "无标题"
except UnicodeDecodeError:
return "解码错误"
3.2 安全连接处理
context = ssl.create_default_context()
if scheme == 'https':
secure_sock = context.wrap_socket(sock, server_hostname=host)
secure_sock.connect((host, port))
secure_sock.send(request_text.encode())
response = receive_all(secure_sock)
四、关键技术解析
4.1 TCP粘包问题解决方案
通过固定头部长度的方式解决:
- 先发送4字节的包长度信息
- 接收方先读取包头获取数据长度
- 根据长度读取完整数据包
4.2 多线程资源管理
- 使用守护线程处理后台任务
- 主线程控制程序生命周期
- 全局资源使用线程安全的数据结构
4.3 HTTP协议解析要点
- 严格处理状态码(如301重定向)
- 正确处理Transfer-Encoding
- 处理分块传输编码(chunked encoding)
五、性能优化建议
- 连接池技术:客户端使用连接池复用TCP连接
- 素数计算优化:采用Miller-Rabin概率素数测试算法
- 内存管理:使用Bloom Filter处理大素数集合
- 异步IO:考虑asyncio替代多线程方案