TCP/IP協議是什麼
TCP和UDP處在同一層---運輸層,但是TCP和UDP最不同的地方是,TCP提供了一種可靠的數據傳輸服務,TCP是面向連接的,也就是説,利用TCP通信的兩台主機首先要經歷一個“撥打電話”的過程,等到通信準備結束才開始傳輸數據,最後結束通話。所以TCP要比UDP可靠的多,UDP是把數據直接發出去,而不管對方是不是在收信,就算是UDP無法送達,也不會產生ICMP差錯報文,這一經時重申了很多遍了。
把TCP保證可靠性的簡單工作原理:
應用數據被分割成TCP認為最適合發送的數據塊。這和UDP完全不同,應用程序產生的 數據報長度將保持不變。由TCP傳遞給IP的信息單位稱為報文段或段
當TCP發出一個段後,它啟動一個定時器,等待目的端確認收到這個報文段。如果不能 及時收到一個確認,將重發這個報文段.
當TCP收到發自TCP連接另一端的數據,它將發送一個確認。這個確認不是立即發送,通常將推遲幾分之一秒.
TCP將保持它首部和數據的檢驗和。這是一個端到端的檢驗和,目的是檢測數據在傳輸 過程中的任何變化。如果收到段的檢驗和有差錯, T P將丟棄這個報文段和不確認收到此報文段(希望發端超時並重發)。
既然TCP報文段作為IP數據報來傳輸,而IP數據報的到達可能會失序,因此TCP報文段 的到達也可能會失序。如果必要, TCP將對收到的數據進行重新排序,將收到的數據以正確的順序交給應用層。
TCP還能提供流量控制。TCP連接的每一方都有固定大小的緩衝空間。TCP的接收端只允許另一端發送接收端緩衝區所能接納的數據。這將防止較快主機致使較慢主機的緩衝區溢出。
從這段話中可以看到,TCP中保持可靠性的方式就是超時重發,這是有道理的,雖然TCP也可以用各種各樣的ICMP報文來處理這些,但是這也不是可靠的,最可靠的方式就是隻要不得到確認,就重新發送數據報,直到得到對方的確認為止。
TCP的首部和UDP首部一樣,都有發送端口號和接收端口號。但是顯然,TCP的.首部信息要比UDP的多,可以看到,TCP協議提供了發送和確認所需要的所有必要的信息。可以想象一個TCP數據的發送應該是如下的一個過程。
雙方建立連接
發送方給接受方TCP數據報,然後等待對方的確認TCP數據報,如果沒有,就重新發,如果有,就發送下一個數據報。
接受方等待發送方的數據報,如果得到數據報並檢驗無誤,就發送ACK(確認)數據報,並等待下一個TCP數據報的到來。直到接收到FIN(發送完成數據報)
中止連接
可以想見,為了建立一個TCP連接,系統可能會建立一個新的進程(最差也是一個線程),來進行數據的傳送
--
TCP協議
TCP是一個面向連接的協議,在發送輸送之前 ,雙方需要確定連接。而且,發送的數據可以進行TCP層的分片處理。
TCP連接的建立過程 ,可以看成是三次握手 。而連接的中斷可以看成四次握手 。
1.連接的建立
在建立連接的時候,客户端首先向服務器申請打開某一個端口(用SYN段等於1的TCP報文),然後服務器端發回一個ACK報文通知客户端請求報文收到,客户端收到確認報文以後再次發出確認報文確認剛才服務器端發出的確認報文(繞口麼),至此,連接的建立完成。這就叫做三次握手。如果打算讓雙方都做好準備的話,一定要發送三次報文,而且只需要三次報文就可以了。
可以想見,如果再加上TCP的超時重傳機制,那麼TCP就完全可以保證一個數據包被送到目的地。
2.結束連接
TCP有一個特別的概念叫做half-close,這個概念是説,TCP的連接是全雙工(可以同時發送和接收)連接,因此在關閉連接的時候,必須關閉傳和送兩個方向上的連接。客户機給服務器一個FIN為1的TCP報文,然後服務器返回給客户端一個確認ACK報文,並且發送一個FIN報文,當客户機回覆ACK報文後(四次握手),連接就結束了。
3.最大報文長度
在建立連接的時候,通信的雙方要互相確認對方的最大報文長度(MSS),以便通信。一般這個SYN長度是MTU減去固定IP首部和TCP首部長度。對於一個以太網,一般可以達到1460字節。當然如果對於非本地的IP,這個MSS可能就只有536字節,而且,如果中間的傳輸網絡的MSS更加的小的話,這個值還會變得更小。
4.客户端應用程序的狀態遷移圖
客户端的狀態可以用如下的流程來表示:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
以上流程是在程序正常的情況下應該有的流程,從書中的圖中可以看到,在建立連接時,當客户端收到SYN報文的ACK以後,客户端就打開了數據交互地連接。而結束連接則通常是客户端主動結束的,客户端結束應用程序以後,需要經歷FIN_WAIT_1,FIN_WAIT_2等狀態,這些狀態的遷移就是前面提到的結束連接的四次握手。
5.服務器的狀態遷移圖
服務器的狀態可以用如下的流程來表示:
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
在建立連接的時候,服務器端是在第三次握手之後才進入數據交互狀態,而關閉連接則是在關閉連接的第二次握手以後(注意不是第四次)。而關閉以後還要等待客户端給出最後的ACK包才能進入初始的狀態。
服務器設計
前面曾經講述過UDP的服務器設計,可以發現UDP的服務器完全不需要所謂的併發機制,它只要建立一個數據輸入隊列就可以。但是TCP不同,TCP服務器對於每一個連接都需要建立一個獨立的進程(或者是輕量級的,線程),來保證對話的獨立性。所以TCP服務器是併發的。而且TCP還需要配備一個呼入連接請求隊列(UDP服務器也同樣不需要),來為每一個連接請求建立對話進程,這也就是為什麼各種TCP服務器都有一個最大連接數的原因。而根據源主機的IP和端口號碼,服務器可以很輕鬆的區別出不同的會話,來進行數據的分發。
TCP的交互數據流
對於交互性要求比較高的應用,TCP給出兩個策略來提高發送效率和減低網絡負擔:(1)捎帶ACK。(2)Nagle算法(一次儘量多的發數據)
捎帶ACK的發送方式
這個策略是説,當主機收到遠程主機的TCP數據報之後,通常不馬上發送ACK數據報,而是等上一個短暫的時間,如果這段時間裏面主機還有發送到遠程主機的TCP數據報,那麼就把這個ACK數據報“捎帶”着發送出去,把本來兩個TCP數據報整合成一個發送。一般的,這個時間是200ms。可以明顯地看到這個策略可以把TCP數據報的利用率提高很多。
Nagle算法
上過bbs的人應該都會有感受,就是在網絡慢的時候發貼,有時鍵入一串字符串以後,經過一段時間,客户端“發瘋”一樣突然回顯出很多內容,就好像數據一下子傳過來了一樣,這就是Nagle算法的作用。
Nagle算法是説,當主機A給主機B發送了一個TCP數據報並進入等待主機B的ACK數據報的狀態時,TCP的輸出緩衝區裏面只能有一個TCP數據報,並且,這個數據報不斷地收集後來的數據,整合成一個大的數據報,等到B主機的ACK包一到,就把這些數據“一股腦”的發送出去。雖然這樣的描述有些不準確,但還算形象和易於理解,我們同樣可以體會到這個策略對於低減網絡負擔的好處。
在編寫插口程序的時候,可以通過TCP_NODELAY來關閉這個算法。並且,使用這個算法看情況的,比如基於TCP的X窗口協議,如果處理鼠標事件時還是用這個算法,那麼“延遲”可就非常大了。
-
如何理解Javascript的caller,callee,call,apply區別
在提到上述的概念之前,首先想説説javascript中函數的隱含參數:argumentsarguments該對象代表正在執行的函數和調用它的函數的參數。[function.]arguments[n]參數function:選項。當前正在執行的Function對象的名字。n:選項。要傳遞給Function對象的從0開始的參數值...
-
關於JavaScript學習筆記之Cookie對象
JavaScriptCookieCookie對象:Cookie是一種以文件的形式保存在客户端硬盤的Cookies文件夾中的'用户數據信息(Cookie數據)。Cookie文件由所訪問的Web站點建立,以長久的保存客户端與Web站點間的會話數據,並且該Cookie數據只允許被所訪問的Web站點進行讀取。Cookie文...
-
網站設計首頁要注意的事項
網站設計首頁的時候要注意些什麼?哪些是必須要注意的?下面就來和小編一起看看網站設計首頁要注意的事項吧。1.用户友好性:提高首頁的用户友好性,能夠大大增加留住用户的可能性,更進一步的`話則是能提高用户的黏着度,取得良好的用户轉化效益。而用户的友好性主要體...
-
javascript閉包的定義及應用實例分析
官方解釋“閉包”是一個擁有許多變量和綁定了這些變量的環境表達式(通常是一個函數),因而這些變量也是環境表達式的一部分。通俗解釋Javascript中所有的函數都是一個閉包。不過一般來説,嵌套的function產生的閉包更為強大,也是大部分時候我們所説的“閉包”。看如下...