2016年11月9日 星期三

TCP TIME_WAIT的釋義(轉)

在實務中, 許多情況下, 可能是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 ProtocolTCP State Diagram
TCP Connection Termination
Socket FAQ -- 2.7 please explain the TIME_WAIT state

2015年6月25日 星期四

SDK, API and Framework(轉載自山川浮雲)

何謂 Library 、 API 、 Framework 、 SDK


程式語言提供的,只有語法、變數宣告…這類的定義。
使用者必須自行組裝 if..else ,構成邏輯,形成功能。
所以我們需要學習資料結構(Data Sturcture)、演算法(Algorithm)的知識,
才能使得程式有所功能。
但因人壽有限,知識無窮。
我們手上並沒有那麼多時間去做那麼多事(你知道嗎? sin、cos也是用algorithm迭代出近似值,而怎麼迭代又要延伸到數學問題這個層面),
所以每個語言基本上都提供了 Standard Library ,像是 C++的 STL (Standard template library );Java的 JavaSE Api;C#的 BCL (Basic Class Library);Python 、Ruby(也有,沒特別的名字。
裡面都會提供數學函數、Max/min比較函數、資料結構(Map/list/range/array/hashTable/vector)、String定義、字元操作、基本的sorting algorithm。
如果要更進階的 algorithm ,就必須自己用這些工具組裝起來,但我想,現在語言的發展,沒有這些 standard library 做不出來 algorithm。
「不要重複造輪子」,這是常用來闡述 reuse 概念的句子。當我們需要一個 algorithm 而 standard library 沒有時,所有的語言都允許你引用(reference)其他人寫好的code。
當一組(可能數個到數十個檔案組成的)code,提供一些功能時,才被稱之為「library」(函數庫、函式庫)。 Library 提供一系列操作 Library 的 setting、data structure 的 function 或 class member function,這類稱之為「API」(Access programming interface)。
API的定義有待商榷,有些人只拿來指 os 提供的函數,或者 web 服務者提供的呼叫函數(url or what ever)
有些在某領域已經開發多年,歸納出一些系統解耦的規則,並將之以某種語言寫好發布,開發者只要遵造它的規則,什麼地方放什麼東西,就可以運作了。這類東西叫做 Framework。
像是近年很火的 MVC(Model-view-controller),php的Laravel 4的MVC,只要你寫一個 class 繼承 model class,放在/model資料夾,他自己就會bind進系統,讓開發員只要專注model本身就行,這種事就是Framework。
Framework提供標準,Developer遵守標準,繼承對東西、放對位置,剩下資源管理什麼的都由Framework幫你處理。這就是 Framework (框架)。
在軟體工程(softwar engineering)的框架(framework)跟這裡的概念是不太相同的,我這裡是指已經發布成一套code並能使用的東西,不懂的話請參考:PHP的Laravel4、Python的Django、Ruby的Ruby on Rails、Go的beego、Java的Spring,C++的CppCMS。
當程式這項工程越來越龐大,開始有測試的需求;有些重複的class撰寫工作,我們希望自動產生;開發使用的Libraray或Framework使用的Libraray太多了,IDE未必能全部幫你 autocomplete,這時候我們希望建立一個對該工程優化的環境。這時候就有了「SDK」(Software Developer Kit)。
簡單來說,Android SDK,提供了android simulator、test unit、resource automatic generator、layout setter…這些工具已經是各自獨立的小程式,幫你維護每個Android APP,有些動作,不用再到cmd輸入命令、到xxx.java修改檔案。而是使用它提供的 kit (小工具)來幫你完成。這就是 SDK。
當然事實不是那麼美好,有寫地方你還是要自己下去看原始碼修改除bug (XD)
現在每個mobile app的開發工具都有自己一套app,並且與自己的IDE綁在一起。(windows phone + Visual Studio,iphone + Xcode,Android + android studio)。沒有使用配合的IDE,將無法 Compile。但現在有些Cross-platform有處理掉一些,扯遠了,以後再說吧。
另外,有時候 SDK 只是指它提供了一套結合不同功能的Library的大雜燴Library。譬如,Clanlib它封裝了 opengl、data structure、event loop…等等寫遊戲需要的東西,你只需要 call 他提供的 function,就能享受各種的服務。
再舉個例子,Qt一套Gui Library,但他叫自己SDK,因為它裡面有很多Class來處理不同的問題,而不像上面我說的Library只提供一件事的solution,SDK是集大成、大型的Library(可能橫跨os層、socket、os event、share memory、process communication、render-opengl)。在這個定義下,可能會有額外的小工具,也可以沒有(這時就只是大量的Libraray)。
使用這類的SDK有一個好處,就是你不用再自己處理 Library 之間的一些問題。子系統間溝通有共用的object,這樣使用上也讓開發者方便許多。
好了,這樣就介紹完四種名詞了。希望沒什麼地方講錯,更多的內容以後再補充。
Tags:api framework library sdk