我知道requests.get()
提供了HTTP接口,以便程序员可以向HTTP服务器发出各种请求。
这告诉我必须打开某个端口,以便可以进行请求。
考虑到这一点,如果在响应/完成请求之前停止脚本(例如,通过键盘中断使脚本执行的机器保持连接到Internet)会发生什么情况?
端口/连接是否保持打开状态?
端口/连接是否自动关闭?
答案 0 :(得分:12)
该问题的简短答案是:如果发生任何异常(包括KeyboardInterrupt
和SystemExit
),请求将关闭连接。
请求源代码中的little digging显示requests.get
最终调用了HTTPAdapter.send
方法(这是发生所有魔术的地方)。
在send
方法中发出请求的方式有两种:分块的或不分块的。我们执行哪个send
取决于request.body
和Content-Length
标头的值:
chunked = not (request.body is None or 'Content-Length' in request.headers)
在请求正文为None
或设置了Content-Length
的情况下,requests
将{的高级make use方法的urlopen
{1}}:
urllib3
在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
提供的底层低层连接。在这种情况下,请求仍然可以处理异常,它使用try
/ except
块来执行此操作,该块在获取连接后立即开始,并以:
urllib3
有趣的是,如果没有错误,连接可能不关闭,具体取决于您为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
源中找到分块_put_conn
的{{1}}调用,这可能是一个分段工作流程中的错误)。
答案 1 :(得分:1)
在更低的级别上,当程序退出时,OS内核会关闭该程序打开的所有文件描述符。这些包括网络套接字。