最近遇到 TIME_WAIT 的問題, (server is too busy to wait TIME_WAIT), 認真的去找了資料, 發現果然沒錯, 跟 MSL (maxinum segment length) 有關, 這裡有說明
Truncation of TIME_WAIT:
也有專門的論文討論如何解決喔... (tkwu 學長可以參考參考.. ^^)
Avoiding the TCP TIME_WAIT state at Busy Servers
至於 windows 以及 unix 的設定方式如下
正在測看看會不會有問題, 到時在跟大家說吧... ^^
我沒有聽過 2MSL 啦... 不過書上說的滿合理的... 只是不知道跟你遇到的狀況有沒有直接的關係~~~~
封包的存活時間就是 TTL 啦, 不過一般是用來算 hops 的, 大部分是用來避免 loop 或是過長的路徑發生... 所以 2MSL 所提的封包存活時間不是很確定是啥~~~
至於你遇到的情況我想應該是 TCP 的 3-way handshaking 的關係吧~
你可以作個實驗, 就是用 telnet 連到某個 bbs 或是什麼的, 然後強制把那個 telnet 程式砍掉, 再用 netstat 看會發現剛剛那個 connection 的 state 是 TIME_WAIT,
ex:
Proto Local Address Foreign Address State
TCP 61.228.52.XX:3256 140.114.87.XX:23 TIME_WAIT
而且這個狀態會持續一陣子才會不見, 這就是因為你強制 kill 那個 process, 所以沒有真正的完成 terminate 的 step, OS 會一直等到 timeout 之後才把狀態還原. 這種情況發生在 client 的時候比較沒差, 因為 OS 每次都會選一個沒有被使用的 port 去連結, 但是如果發生在 server 的時候, 由於 service process 突然被砍掉, 原有的連線還沒完成 release 的動作, OS 沒有收到 terminate 的 ack, 所以就會認為那個 port 還在使用中, 直到 timeout 才會被釋放~
這也就是為什麼你的程式如果 run 起來, 但是沒有任何人連上來就 kill 掉的話比較沒差, 可以直接重新執行, 而如果有人正在連線的話就會發生收不到 terminate 的 ack (或許應該說 process 已經死掉了, 所以沒有人去接那個封包, 就算送回來也沒用), OS 就會等到 timeout 才會釋放, 你的程式也得等到那時候才能重新使用那個 port~
2MSL 的問題..?!
以前在寫 tcp server 程式時有時候會發生一種狀況, 就是我把 server 跑起來以後,
再把他 kill 掉, 然後再度把他跑起來時, 就會出現我使用的 port 已經被 bind 住了,
但我確定沒有其它程式在用,也確定我把 server 都關掉了,一定要過一段時間後,
才可以再度跑那支 server 程式.....
最近看書發現到一個名詞...2MSL(Maximum Segment Lifetime)...
他是翻成兩倍的最大封包存活時間, 就是因為網路上的封包可能會因為某些
原因而塞車, 這時舊的 server 程式如果關掉再跑新的 server 程式, 這樣舊的封包
可能會影響新的 server 的運作, 所以才會有這個機制, 也就是等待兩倍的封包存
活時間就可以確保舊封包都不見了.....
請問我有一段時間跑不起來是因為這個原因嗎..?
又, 我該怎麼知道一個封包的存活時間..?
阅读(3712) | 评论(0) | 转发(0) |