分佈式系統能夠總結爲是處於不一樣物理位置的多個進程組成的總體,爲了確保這個總體有效而且高效的對外提供服務,每一個節點之間都有可能須要進行通訊來交換信息,而這個交換信息的過程多數使用的是tcp協議。tcp協議是位於ip層之上的傳輸層協議,在這個傳輸層裏有兩個比較重要的協議:tcp和udp。對於應用層的開發人員來講,用的最多的就是這兩個協議,這也是一些面試官必問的知識點之一面試
不管是tcp仍是udp,都是創建在ip+端口的規則之上,什麼意思呢?也就是說採用tcp和udp的進程都須要一個端口來讀取和寫入數據。算法
tcp協議是可靠的協議,並且是面向鏈接的,創建鏈接的過程會通過三次握手。爲何會是三次握手而不是二次或者四次呢?緩存
說到這個問題,能夠抽象出一個場景,怎麼樣才能肯定一端是和另一端互通的呢?其實很簡單,一端發送給另外一端的消息能順利給我答覆,這就說明兩端是聯通的。tcp協議的三次握手剛好說明了這一點,A和B通訊,只要三次握手,A能獲得B的答覆,B也能獲得A的答覆。網絡
基於ip層發送的報文,在網絡中是沒法肯定是否正確到達對方的。tcp協議在ip協議之上添加了一系列數據結構和算法來保證tcp的數據正確到達。數據結構
說了這麼多,其實能夠把tcp看作是一個有狀態的協議,它能夠根據網絡情況,對方接收狀況等諸多因素來調整本身的發送狀態。socket
相對於tcp協議來講,udp要簡單不少數據結構和算法
udp基於以上特性能夠在網絡環境比較好或者對於丟包不敏感的應用中使用。udp在捨棄了重傳,順序等一些列特性以後,處理速度特別快,在一些不敏感可是實時性要求比較高的場景中應用很是普遍。tcp
在有了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的一個區別。
對於udp來講,過程有點不同。udp是沒有鏈接的,一是不須要三次握手,二是不須要listen和connect,可是仍然須要ip和端口bind,要否則遠端的數據到來的時候,系統會找不到接收程序的。UDP是沒有鏈接狀態的,於是不須要每次鏈接都創建一組Socket,而是隻用一個Socket,就可以和多個客戶端通訊。也正是由於沒有鏈接狀態,每次通訊的時候,調用sendto和recvfrom,都須要傳入 IP 地址和端口。
基於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協議那本書。