You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 18:53:20