python中使用socket進行編程時,發現client的tcp經常處於close_wait狀態:linux中使用命令
# netstat -atpn
原因是server端關掉了tcp串連,給client發送FIN訊號,client的tcp層回了ACK,然後它的socket狀態就處於close_wait狀態。
實驗:
python中,socket在send之前處於close_wait狀態,那麼該send不會報錯,並且執行完之後socket就closed了。再繼續調用send就會報錯。
推理:
說明python的socket.send在發送資料之前會檢查socket的狀態,如果處於close_wait,就執行close(socket)(應用程式層感覺不到哦),然後正常退出。所以再次send時,會拋出異常。
為什麼會一直處close_wait狀態。
當socket處於close_wait時,必須由應用程式層調用close(socket),發送FIN給server端才能變為LAST_ACK,接收到server端回應的ACK後,才變為CLOSED。如果應用程式層不調用close(),那麼socket會一直處於close_wait。[1]
如果我在python中不斷迴圈去調用socket.sendall(),那麼在socket變為close_wait後,通過socket.sendall()也會關閉socket,為什麼它還是一直處在close_wait狀態呢。
原因在於當sendall(data)的data比較大,在data被發送一半時,串連被server端斷掉了。那麼sendall(data)會一直卡在那,也就不會執行到sendall的開始處,去判斷socket狀態,確定是否關閉socket了。
簡單而言,就是socket在變為close_wait之後,根本沒有調用sendall()去關閉socket。
參考文獻:
[1] Explaining Close_Wait - Jane Lewis's Weblog - Site Home - TechNet Blogs
[2] Linux socket通訊出現CLOSE_WAIT狀態的原因與解決方案-fly123456789-ChinaUnix部落格