【问题标题】:Python: What happens if script stops while requests.get() is executing?Python:如果脚本在 requests.get() 执行时停止会发生什么?
【发布时间】:2018-08-13 23:12:32
【问题描述】:

我知道requests.get() 提供了一个HTTP 接口,以便程序员可以向HTTP 服务器发出各种请求。

这告诉我必须在某个地方打开一个端口,这样请求才能发生。

考虑到这一点,如果脚本在请求得到答复/完成之前停止(例如,由于键盘中断,因此正在执行脚本的机器仍然连接到互联网)会发生什么情况?

端口/连接会保持打开状态吗?

端口/连接会自动关闭吗?

【问题讨论】:

    标签: python http python-requests python-requests-html


    【解决方案1】:

    这个问题的简短回答是:请求会在任何异常情况下关闭连接,包括KeyboardInterruptSystemExit

    请求源代码中的little digging 显示requests.get 最终调用HTTPAdapter.send 方法(这是所有魔法发生的地方)。

    send 方法中可以通过两种方式发出请求:分块或不分块。我们执行哪个send 取决于request.bodyContent-Length 标头的值:

    chunked = not (request.body is None or 'Content-Length' in request.headers)
    

    在请求体为None或设置了Content-Length的情况下,requestsurlopen的高级方法make useurlopenurllib3

    if not chunked:
        resp = conn.urlopen(
            method=request.method,
            url=url,
            body=request.body,
            # ...
        )
    

    urllib3.PoolManager.urlopen 方法的finally 块具有处理在try 块未成功执行的情况下关闭连接的代码:

    clean_exit = False
    # ...
    try:
        # ...
        # Everything went great!
        clean_exit = True
    finally:
        if not clean_exit:
            # We hit some kind of exception, handled or otherwise. We need
            # to throw the connection away unless explicitly told not to.
            # Close the connection, set the variable to None, and make sure
            # we put the None back in the pool to avoid leaking it.
            conn = conn and conn.close()
            release_this_conn = True
    

    在响应可以分块的情况下,请求会降低一点,并使用urllib3 提供的底层低级连接。在这种情况下,请求仍然处理异常,它使用try / except 块来处理,该块在获取连接后立即开始,并以:

    low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)
    
    try:
        # ...
    except:
        # If we hit any problems here, clean up the connection.
        # Then, reraise so that we can handle the actual exception.
        low_conn.close()
        raise
    

    有趣的是,如果没有错误,连接可能不会关闭,具体取决于您为urllib3 配置连接池的方式。在成功执行的情况下,连接将被放回连接池(尽管我在 requests 源中找不到分块 send_put_conn 调用,这可能是分块工作中的错误 -流)。

    【讨论】:

      【解决方案2】:

      在低得多的级别上,当程序退出时,操作系统内核会关闭该程序打开的所有文件描述符。其中包括网络套接字。

      【讨论】:

      • 非常有趣。更有趣的是,正如公认的答案所说,如果没有错误,连接可能不会关闭......很高兴探索......
      猜你喜欢
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-21
      • 2021-04-10
      • 1970-01-01
      • 2018-07-20
      相关资源
      最近更新 更多