tcp/ip協議的工作流程如下:
●在源主機上,應用層將一串應用資料流傳送給傳輸層。
●傳輸層將應用層的資料流截成分組,並加上tcp報頭形成tcp段,送交網路層。
●在網路層給tcp段加上包括源、目的主機ip位址的ip報頭,生成乙個ip資料報,並將ip資料報送交鏈路層。
●鏈路層在其mac幀的資料部分裝上ip資料報,再加上源、目的主機的mac位址和幀頭,並根據其目的mac位址,將mac幀發往目的主機或ip路由器。
●在目的主機,鏈路層將mac幀的幀頭去掉,並將ip資料報送交網路層。
●網路層檢查ip報頭,如果報頭中校驗和與計算結果不一致,則丟棄該ip資料報;若校驗和與計算結果一致,則去掉ip報頭,將tcp段送交傳輸層。
●傳輸層檢查順序號,判斷是否是正確的tcp分組,然後檢查tcp報頭資料。若正確,則向源主機發確認資訊;若不正確或丟包,則向源主機要求重發資訊。
●在目的主機,傳輸層去掉tcp報頭,將排好順序的分組組成應用資料流送給應用程式。這樣目的主機接收到的來自源主機的位元組流,就像是直接連線終止協議(四次揮手)接收來自源主機的位元組流一樣。
tcp協議三次握手
(1)客戶端傳送乙個帶syn標誌的tcp報文到伺服器。這是三次握手過程中的報文1。
(2) 伺服器端回應客戶端的,這是三次握手中的第2個報文,這個報文同時帶ack標誌和syn標誌。因此它表示對剛才客戶端syn報文的回應;同時又標誌syn給客戶端,詢問客戶端是否準備好進行資料通訊。
(3) 客戶必須再次回應服務段乙個ack報文,這是報文段3。
連線終止協議(四次揮手)
由於tcp連線是全雙工的,因此每個方向都必須單獨進行關閉。這原則是當一方完成它的資料傳送任務後就能傳送乙個fin來終止這個方向的連線。收到乙個 fin只意味著這一方向上沒有資料流動,乙個tcp連線在收到乙個fin後仍能傳送資料。首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。
(1) tcp客戶端傳送乙個fin,用來關閉客戶到伺服器的資料傳送(報文段4)。
(2) 伺服器收到這個fin,它發回乙個ack,確認序號為收到的序號加1(報文段5)。和syn一樣,乙個fin將占用乙個序號。
(3) 伺服器關閉客戶端的連線,傳送乙個fin給客戶端(報文段6)。
(4) 客戶段發回ack報文確認,並將確認序號設定為收到序號加1(報文段7)。
closed: 這個沒什麼好說的了,表示初始狀態。
listen: 這個也是非常容易理解的乙個狀態,表示伺服器端的某個socket處於監聽狀態,可以接受連線了。
syn_rcvd: 這個狀態表示接受到了syn報文,在正常情況下,這個狀態是伺服器端的socket在建立tcp連線時的三次握手會話過程中的乙個中間狀態,很短暫,基本上用netstat你是很難看到這種狀態的,除非你特意寫了乙個客戶端測試程式,故意將三次tcp握手過程中最後乙個ack報文不予傳送。因此這種狀態時,當收到客戶端的ack報文後,它會進入到established狀態。
syn_sent: 這個狀態與syn_rcvd遙想呼應,當客戶端socket執行connect連線時,它首先傳送syn報文,因此也隨即它會進入到了syn_sent狀態,並等待服務端的傳送三次握手中的第2個報文。syn_sent狀態表示客戶端已傳送syn報文。
established:這個容易理解了,表示連線已經建立了。
fin_wait_1: 這個狀態要好好解釋一下,其實fin_wait_1和fin_wait_2狀態的真正含義都是表示等待對方的fin報文。而這兩種狀態的區別是:fin_wait_1狀態實際上是當socket在established狀態時,它想主動關閉連線,向對方傳送了fin報文,此時該socket即進入到fin_wait_1狀態。而當對方回應ack報文後,則進入到fin_wait_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ack報文,所以fin_wait_1狀態一般是比較難見到的,而fin_wait_2狀態還有時常常可以用netstat看到。
fin_wait_2:上面已經詳細解釋了這種狀態,實際上fin_wait_2狀態下的socket,表示半連線,也即有一方要求close連線,但另外還告訴對方,我暫時還有點資料需要傳送給你,稍後再關閉連線。
time_wait: 表示收到了對方的fin報文,並傳送出了ack報文,就等2msl後即可回到closed可用狀態了。如果fin_wait_1狀態下,收到了對方同時帶fin標誌和ack標誌的報文時,可以直接進入到time_wait狀態,而無須經過fin_wait_2狀態。
closing: 這種狀態比較特殊,實際情況中應該是很少見,屬於一種比較罕見的例外狀態。正常情況下,當你傳送fin報文後,按理來說是應該先收到(或同時收到)對方的ack報文,再收到對方的fin報文。但是closing狀態表示你傳送fin報文後,並沒有收到對方的ack報文,反而卻也收到了對方的fin報文。什麼情況下會出現此種情況呢?其實細想一下,也不難得出結論:那就是如果雙方幾乎在同時close乙個socket的話,那麼就出現了雙方同時傳送fin報文的情況,也即會出現closing狀態,表示雙方都正在關閉socket連線。
close_wait: 這種狀態的含義其實是表示在等待關閉。怎麼理解呢?當對方close乙個socket後傳送fin報文給自己,你系統毫無疑問地會回應乙個ack報文給對方,此時則進入到close_wait狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有資料傳送給對方,如果沒有的話,那麼你也就可以close這個socket,傳送fin報文給對方,也即關閉連線。所以你在close_wait狀態下,需要完成的事情是等待你去關閉連線。
last_ack: 這個狀態還是比較容易好理解的,它是被動關閉一方在傳送fin報文後,最後等待對方的ack報文。當收到ack報文後,也即可以進入到closed可用狀態了。
為什麼建立連線協議是三次握手,而關閉連線卻是四次握手呢?
這是因為服務端的listen狀態下的socket當收到syn報文的建連請求後,它可以把ack和syn(ack起應答作用,而syn起同步作用)放在乙個報文裡來傳送。但關閉連線時,當收到對方的fin報文通知時,它僅僅表示對方沒有資料傳送給你了;但未必你所有的資料都全部傳送給對方了,所以你可以未必會馬上會關閉socket,也即你可能還需要傳送一些資料給對方之後,再傳送fin報文給對方來表示你同意現在可以關閉連線了,所以它這裡的ack報文和fin報文多數情況下都是分開傳送的
java 基礎 TCP IP協議
1.tcp ip協議起源概述 tcp ip協議源於1969年,是針對internet開發的一種體系結構和協議標準,其目的在於解決異種計算機網路的通訊問題。使得網路在互聯時能為使用者提供一種通用 一致的通訊服務。是國際網際網路internet採用的協議標準。tcp 傳輸控制協議 ip 網際網路絡協議 ...
基於TCP IP協議的網路程式設計
基於tcp ip協議的網路程式設計 定義變數 獲得winsock版本 載入winsock庫 初始化 建立套接字 設定套接字選項 關閉套接字 解除安裝winsock庫 釋放所有資源 整個程式架構分為兩大部分,伺服器端客戶端。伺服器socket程式流程 socket bind listen accept...
基於TCP IP協議實現檔案傳輸
public class fileserver extends thread override public void run 將map集合傳送到客戶端 oos.writeobject map oos.flush 2.接收客戶端傳送的檔案序號 scanner sc new scanner s.get...