程序員修神之路--簡約而不簡單的分布式通信基石


分布式系統可以總結為是處於不同物理位置的多個進程組成的整體,為了確保這個整體有效並且高效的對外提供服務,每個節點之間都有可能需要進行通信來交換信息,而這個交換信息的過程多數使用的是tcp協議。tcp協議是位於ip層之上的傳輸層協議,在這個傳輸層里有兩個比較重要的協議:tcp和udp。對於應用層的開發人員來說,用的最多的就是這兩個協議,這也是一些面試官必問的知識點之一

無論是tcp還是udp,都是建立在ip+端口的規則之上,什么意思呢?也就是說采用tcp和udp的進程都需要一個端口來讀取和寫入數據。

TCP協議

tcp協議是可靠的協議,而且是面向連接的,建立連接的過程會經過三次握手。為什么會是三次握手而不是二次或者四次呢?

image

說到這個問題,可以抽象出一個場景,怎么樣才能確定一端是和另外一端互通的呢?其實很簡單,一端發送給另一端的消息能順利給我答復,這就說明兩端是聯通的。tcp協議的三次握手恰好說明了這一點,A和B通信,只要三次握手,A能得到B的答復,B也能得到A的答復。

基於ip層發送的報文,在網絡中是無法確定是否正確到達對方的。tcp協議在ip協議之上添加了一系列數據結構和算法來保證tcp的數據正確到達。

  1. tcp的數據包是有編號的,這么做主要是為了解決順序問題,如果沒有編號,對方怎么確定順序呢?另外一點,編號是為了發送方來確認哪些包已經正確到達對方
  2. 當tcp的數據包被接收方接收,接收方需要發送確認包給發送方,發送方在接收到確認包之后會把對應的數據包做狀態修改,由於每個數據包其實有超時機制,在超時之后,發送方會進行重試
  3. tcp是面向字節流的,發送的時候發的是一個字節流,這是tcp自己的狀態維護的事情。

說了這么多,其實可以把tcp看做是一個有狀態的協議,它可以根據網絡狀況,對方接收情況等諸多因素來調整自己的發送狀態。

UPP協議

相對於tcp協議來說,udp要簡單很多

  1. udp協議不需要建立連接,這就意味着發送方只要知道對方的ip和端口,就可以發送,基於這一點可以做廣播。
    2.udp協議不負責可靠交付,因為它不像tcp協議那樣有一堆的算法和數據結構來做保證。
  2. udp是基於數據報形式的,一個一個的發,一個一個的接收。而且udp數據的發送不會根據因為網絡環境的阻塞而改變

udp基於以上特性可以在網絡環境比較好或者對於丟包不敏感的應用中使用。udp在舍棄了重傳,順序等一些列特性之后,處理速度特別快,在一些不敏感但是實時性要求比較高的場景中應用非常廣泛。

Socket

在有了tcp和udp協議之后,進程間通信的基石就有了。但是總不能每次通信自己都需要寫tcp的三次握手等這些復雜過程吧。為了屏蔽這些復雜的過程,使通信程序簡單,在tcp和udp協議之上,便抽象出來了socket這個概念。

所謂套接字(Socket),就是對網絡中不同主機上的應用進程之間進行雙向通信的端點的抽象。一個套接字就是網絡上進程通信的一端,提供了應用層進程利用網絡協議交換數據的機制。從所處的地位來講,套接字上聯應用進程,下聯網絡協議棧,是應用程序通過網絡協議進行通信的接口,是應用程序與網絡協議根進行交互的接口

socket是區分服務端和客戶端的,本地的socket與遠程的一個socket建立連接的過程,其實就是tcp協議三次握手的過程。一旦socket連接建立,就可以利用socket抽象出來的read或者write方法來進行通信了。

socket需要指定使用的IP協議,還需要指定使用的是tcp還是udp協議。基於tcp協議的服務端的socket需要bind一個端口來listen並且accept客戶端的socket連接。這也是服務端socket和客戶端socket的一個區別。
image

對於udp來說,過程有點不一樣。udp是沒有連接的,一是不需要三次握手,二是不需要listen和connect,但是仍然需要ip和端口bind,要不然遠端的數據到來的時候,系統會找不到接收程序的。UDP是沒有連接狀態的,因而不需要每次連接都建立一組Socket,而是只用一個Socket,就能夠和多個客戶端通信。也正是因為沒有連接狀態,每次通信的時候,調用sendto和recvfrom,都需要傳入 IP 地址和端口。

image

基於tcp的socket在內核中都有一個發送緩沖區和接收緩沖區,tcp的雙工工作模式以及tcp的滑動窗口就是依賴於這兩個獨立的buffer以及buffer的數據填充狀態。接收緩沖區把數據緩存入內核之中,如果對應的應用一直沒有調用socket的read方法進行數據讀取,則此數據會一直被緩存在接收緩沖區中,如果接收緩沖區滿了,便會通知對方socket,以調整對方socket的發送窗口大小,這就是滑動窗口的實現。如果對方仍然持續發送數據,接收方在接收緩沖區沒有被讀取的情況下將丟棄后到的數據,這就是tcp的流量控制。對於udp來說,它沒有真正的發送緩沖區,只要有數據就會發送,無論對方能否正常正確接收,這也是udp丟包的原因之一,但是udp的socket 和tcp的socket一樣都會有接收緩沖區,而且行為也一樣。

寫在最后

有的面試官吹水,號稱http長連接,這個說法其實是不准確的,長連接和短連接是針對tcp協議而言,http只是建立在tcp/ip協議之上的應用層的一個協議。總體而言,tcp和udp設計的數據結構和算法有很多,這里只是粗略的說了一下,有興趣的同學可以去研究tcp協議那本書。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM