每個TCP通訊的的socket的內核裏面都會有一個發送緩衝區和接收緩衝區linux
發送端 : send 報文 -- TCP發送緩衝區 --
接收端 :TCP接收緩衝區 -- receive TCP報文ajax
-1. TCP協議的兩端分別爲發送者A和接收者B,因爲是全雙工協議,所以A和B應該分別維護着一個獨立的發送緩衝區和接收緩衝區,因爲對等性(A發B收和B發A收),咱們以A發送B接收的狀況做爲例子;
-2. 發送窗口是發送緩存中的一部分,是能夠被TCP協議發送的那部分,其實應用層須要發送的全部數據都被放進了發送者的發送緩衝區;
-3. 發送窗口中相關的有四個概念:已發送並收到確認的數據(再也不發送窗口和發送緩衝區以內)、已發送但未收到確認的數據(位於發送窗口之中)、容許發送但還沒有發送的數據以及發送窗口外發送緩衝區內暫時不容許發送的數據;
-4. 每次成功發送數據以後,發送窗口就會在發送緩衝區中按順序移動,將新的數據包含到窗口中準備發送;
TCP創建鏈接的初始,B會告訴A本身的接收窗口大小,好比爲‘20’緩存
發送一個消息,發送端必須準備好--發送緩衝區滿,阻塞send操做,等緩衝區全部數據所有發出去後,send才能夠繼續發送
接收一個消息,接收端必須準備好 -- 接收緩衝區有一個大小,好比10,只有填滿這個緩衝區,開始接收,接收完了,外面才能夠再發送數據過來多線程
解決IO線程和socket一個解耦問題,引入一個事件機制來達到解耦目的,進程底層存在一個IO的線程調度,它不斷掃描每個socket緩衝區,當發現一個寫緩衝區爲空的時候,會產生一個socket可寫事件通知一個線程去寫數據,一次寫不完 會等到下一次。 對於接收端,發現接收緩衝區可讀,會發送一個可讀事件給線程,若是不可讀的話,這個線程就不會阻塞,能夠去幹其餘事情。異步
這個事件機制,就是IO多路複用的模型,linux裏面可使用select, 把線程扔到select裏面
從流程上來看,使用select函數進行IO請求和同步阻塞模型沒有太大的區別,甚至還多了添加監視socket,以及調用select函數的額外操做,效率更差。可是,使用select之後最大的優點是用戶能夠在一個線程內同時處理多個socket的IO請求。用戶能夠註冊多個socket,而後不斷地調用select讀取被激活的socket,便可達到在同一個線程內同時處理多個IO請求的目的。而在同步阻塞模型中,必須經過多線程的方式才能達到這個目的。socket
同步和異步,表明當前請求,好比 ajax是異步tcp
針對當前請求的阻塞IO
同步阻塞,
同步非阻塞
異步阻塞
異步非阻塞函數