Python Socket网络请求代码修改后无限运行问题求助
问题排查:Socket请求网页后程序无限运行
问题现象
原代码可正常获取指定网页内容,但修改为支持手动输入网址后,程序陷入无限循环无法终止。
核心问题分析
1. HTTP请求格式错误(最关键原因)
构造请求时用了r"HTTP/1.0\r\n\r\n"原始字符串,和前面的f-string拼接后,\r\n会被当作字面量字符(实际发送的是\\r\\n),服务器无法识别这是请求结束的标记,因此不会关闭连接,导致mysock.recv(512)一直阻塞等待数据,程序进入无限循环。
原正确代码中'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n'的\r\n是转义后的换行符,服务器能正确识别请求边界。
2. 请求路径不符合HTTP规范
如果输入完整URL(如http://data.pr4e.org/romeo.txt),GET请求里的目标应该是路径/romeo.txt,而非完整网址。用完整URL发送请求会让服务器无法正确处理,同样不会正常终止连接。
3. 异常处理逻辑缺陷
try块仅包裹了输入和连接步骤,若此处出错(如URL解析失败、连接失败),except打印错误后程序仍会继续执行后续的send和循环操作,此时socket可能未正常连接,会引发更多错误甚至阻塞。
修复后的代码
import socket import re mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: webad = input("Enter your web address:") # 解析主机名和请求路径 url_match = re.match(r"^(?:https?:\/\/)?(?:www\.)?([^\/\s]+)(\/.*)?$", webad) if not url_match: raise ValueError("输入的URL格式无效") host_name = url_match.group(1) # 若没有路径,默认请求根目录 request_path = url_match.group(2) if url_match.group(2) else "/" mysock.connect((host_name, 80)) # 构造符合HTTP规范的请求,使用普通字符串的\r\n作为换行 request_cmd = f"GET {request_path} HTTP/1.0\r\n\r\n".encode() mysock.send(request_cmd) # 接收并打印响应 while True: data = mysock.recv(512) if len(data) < 1: break print(data.decode(), end='') except Exception as e: print(f"错误信息: {e}") finally: # 无论是否出错,确保socket关闭 mysock.close()
修复说明
- 修正请求格式:直接在f-string中使用
\r\n,确保服务器能识别请求结束标记。 - 正确解析URL:分离主机名和请求路径,符合HTTP 1.0的请求规范。
- 优化异常处理:将所有核心操作放入
try块,用finally保证socket资源被释放,避免异常后资源泄漏;增加URL格式校验,提前反馈错误。 - 避免无效执行:若URL解析或连接失败,不会执行后续的发送和循环逻辑。
内容的提问来源于stack exchange,提问作者Navid Asgari
相关产品推荐
相关产品推荐

