[英]python SimpleHTTPRequestHandler server leaves socket in TIME_WAIT state after exit
[英]Closing socket after subprocess.Popen leaves socket in TIME_WAIT as long as child process is still running
在Windows 7上:
給定此服務器代碼:
# in server.py
if __name__ == '__main__':
serversock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# uncommenting this won't help
#serversock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversock.bind(('',8888))
serversock.listen(5)
# accept and receive dummy data from client
clientsock,address = serversock.accept()
data = clientsock.recv(1024)
# as long as calc.exe is running, I can't do this again
subprocess.Popen(r"c:\windows\system32\calc.exe")
# letting client close first still won't help
time.sleep(3)
# closing won't help either
clientsock.close()
serversock.close()
和客戶端代碼
# in client.py
if __name__ == '__main__':
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 8888))
s.sendall('Hello, world')
# close early to help prevent TIME_WAIT on server, but doesn't help
s.close()
首先運行服務器,然后客戶端將啟動計算器應用程序。
當計算器應用仍在運行時,我無法再次運行服務器 。 它會抱怨
python server.py (ok)
python client.py (ok)
python server.py (boom!)
socket.error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
如果我關閉計算器應用程序,則可以再次運行服務器...在Mac上不會發生這種情況。
啟用SO_REUSEADDR只會使錯誤消失,但是客戶端無法訪問服務器。
在上面的示例中,我專門讓客戶端首先關閉,這樣服務器套接字就不會進入TIME_WAIT。
所以問題是:
解決方案:
問題在於計算器的父進程保留了一些文件描述符。 因此,將close_fds = True添加到Popen將確保所有內容均正確釋放。
subprocess.Popen(r"c:\windows\system32\calc.exe", close_fds=True)
在子進程之后關閉套接字。只要子進程仍在運行,Popen會將套接字留在TIME_WAIT中
不,不是。 它將它留在TIME_WAIT中固定的時間,即2或4分鍾。 關閉之后,它與子進程完全無關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.