在實務中, 許多情況下, 可能是Server Socket出現了問題, 勢必採取關閉原有的Sever Socket, 再隨即重新啟動新建的Server Socket. 但此刻會發生一個問題, 就是相隔時間過短, 在新建的Sever Socket進行bind()的程序時, 系統會出現一錯誤訊息"the address already in use".
照一般想法, Server Socket都已Close, 理應已釋放出該IP Address之資源, 怎會出現這個令人莫名的訊息呢??
關鍵在於TCP建立於多次的握手協定的基礎上, 以達到保證訊息傳遞的完整性.
由於TPC是全雙工傳輸, 換言之, 雙向的傳輸必須單獨進行關閉, 原則上主動請求關閉的一方A, 藉由發送FIN來請求終止這個方向的連接. 被動關閉的一方B, 收到FIN表示A-->B的方向已無資料進行傳送, 此時B-->A仍是可以進行資料傳送, 待B執行被動關閉.
簡言之, A欲進行關閉傳輸時, 必須通知B並確認, 而B欲進行關閉傳輸時, 也必須通知A並確認.
關閉連線:(如上圖所示)
(1) 當處於ESTABLISHED狀態時, TCP B欲主動關閉連線, 發送FIN至TCP A, 進入到FIN-WAIT-1狀態, 等待TCP A回應ACK, 表示等待確認TCP A得知TCP B要關閉連線
(2) 當TCP A收到TCP B的FIN時, 立即回應ACK給TCP B, 進入到CLOSE-WAIT狀態, 表示須等到應用程序沒有任何資料要傳送給TCP B, TCP A才決定關閉連線
(3) TCP B收到TCP A回應的ACK, 表示確認TCP A得知TCP B要關閉連線, 此刻等待TCP A發送FIN
(4) TCP A決定關閉連線, 發送FIN至TCP B, 進入到LAST-ACK狀態, 等待TCP B回應ACK, 表示等待確認TCP B得知TCP A要關閉連線
(5) TCP B收到TCP A的FIN後, 隨即回應ACK, 進入TIME_WAIT狀態, 表示TCP B得知TCP A要關閉連線, 且等待2MSL時間, 以防TCP A再次發送FIN
(6) TCP A收到TCP B回應的ACK後, 進入CLOSED狀態, 表示TCP A已確認TCP B已得知它要關閉連線, 才進行關閉連線
(7) TCP B等待2MSL時間, 才進入CLOSED狀態, 關閉連線, 並自連線表中移除
在上述的第(5),(7)點, 此刻TIME-WAIT的用意在於, 雖TCP B已確認TCP A要關閉連線, 且回應了ACK給TCP A, 但不保證TCP A會收到ACK, 一旦ACK遺漏, TCP A會再次發送FIN給TCP B, 再次進行確認, 所以TCP B須進入TIME-WAIT狀態, 等待2MSL時間, 預防TCP A會再次發送FIN, 進行連線關閉的確認
different states of a TCP connection:
LISTEN : awaiting a connection request from client (監聽客戶端的連線請求)
SYN-SENT : a SYN has been sent to server, and client is awaiting the ACK of SYN (發送SYN, 並等待服務端回應SYN的ACK)
SYN-RECEIVED : a SYN has been received from client, a SYN with ACK has been sent to client, and server is awaiting the ACK of SYN (接收客戶端的SYN, 另傳送SYN+ACK(SYN)給客戶端, 並等待客戶端回應SYN的ACK)
ESTABLISHED : the three-way handshake has been completed, and established the connection (完成握手協定, 並建立連線)
FIN-WAIT-1 : the local AP has issued a close. active TCP has sent a FIN to passive TCP, and is awaiting an ACK of FIN (主動端發出FIN至被動端, 並等待被動端回應FIN的ACK)
FIN-WAIT-2 : a previous FIN has been sent to passiveTCP, and received an ACK of FIN from passive TCP. active TCP is awaiting a FIN from the passive TCP (成功接收到先前傳送至被動端FIN的ACK, 此刻等待被動端傳送FIN)
CLOSE-WAIT : passive TCP has received a FIN from active TCP, and has sent an ACK of FIN to active TCP. passive TCP is awaiting a close request from remote AP before sending a FIN (被動端已接收主動端的FIN, 並傳送FIN的ACK至主動端, 此刻等待AP要求關閉連線)
LAST-ACK : previously a FIN has been received from active TCP, and an ACK of FIN has been sent to active TCP, and a FIN has been sent to active TCP. passive TCP is awaiting an ACK of FIN (先前收到主動端的FIN, 且傳送FIN的ACK給主動端, 另被動端傳送FIN給主動端, 此刻被動端等待主動端回應FIN的ACK)
TIME-WAIT : FINs have been received and ACK has been sent passive TCP. active TCP is waiting 2MSLs to remove the connection from the connection table (收到被動端的FIN, 並傳送ACK至被動端, 此刻主動端會等待2MSL的時間才將連線關閉)
CLOSED : a connection has been removed from the connection table (連線不存在於連線表)
參考資料:
Transmission Control Protocol
TCP State Diagram
TCP Connection Termination
Socket FAQ -- 2.7 please explain the TIME_WAIT state
沒有留言:
張貼留言