1 回答

TA貢獻(xiàn)1820條經(jīng)驗(yàn) 獲得超2個(gè)贊
您所描述的是預(yù)期的有據(jù)可查的行為:
注意 close() 釋放與連接關(guān)聯(lián)的資源,但不一定立即關(guān)閉連接。如果要及時(shí)關(guān)閉連接,請(qǐng)?jiān)?close() 之前調(diào)用 shutdown()。
有關(guān)此行為的一些進(jìn)一步詳細(xì)信息仍然可以在 CPython howto 文檔中找到:
嚴(yán)格來(lái)說(shuō),您應(yīng)該在關(guān)閉套接字之前對(duì)其使用 shutdown 。關(guān)閉是對(duì)另一端套接字的建議。根據(jù)您傳遞的參數(shù),它可能意味著“我不會(huì)再發(fā)送,但我仍然會(huì)聽(tīng)”,或者“我不聽(tīng),很好的擺脫!”。然而,大多數(shù)套接字庫(kù)已經(jīng)習(xí)慣了程序員忽略使用這一禮儀,通常關(guān)閉與 shutdown() 相同;關(guān)閉()。因此在大多數(shù)情況下,不需要顯式關(guān)閉。
有效使用 shutdown 的一種方法是使用類似 HTTP 的交換??蛻舳税l(fā)送請(qǐng)求,然后執(zhí)行關(guān)閉(1)。這告訴服務(wù)器“該客戶端已完成發(fā)送,但仍然可以接收。” 服務(wù)器可以通過(guò)接收 0 字節(jié)來(lái)檢測(cè)“EOF”。它可以假設(shè)它具有完整的請(qǐng)求。服務(wù)器發(fā)送回復(fù)。如果發(fā)送成功完成,那么客戶端確實(shí)仍在接收。
Python 在自動(dòng)關(guān)閉方面更進(jìn)了一步,它表示當(dāng)套接字被垃圾回收時(shí),如果需要它會(huì)自動(dòng)關(guān)閉。但依賴這一點(diǎn)是一個(gè)非常不好的習(xí)慣。如果您的套接字在沒(méi)有執(zhí)行關(guān)閉的情況下就消失了,另一端的套接字可能會(huì)無(wú)限期地掛起,認(rèn)為您只是速度慢。完成后請(qǐng)關(guān)閉套接字。
解決方案
關(guān)閉之前調(diào)用 shutdown。
例子
with futures.ThreadPoolExecutor() as executor: con = HTTPConnection('httpbin.org') future = executor.submit(get, con, '/delay/10') done, not_done = futures.wait([future], timeout=5) con.sock.shutdown() con.sock.close()
添加回答
舉報(bào)