軌跡系列7——Socket總結及實現基於TCP或UDP的809協議方法


文章版權由作者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/

1.背景

在上一篇博客中我詳細介紹了809協議的內容。809協議規范了通信的報文,通信的規則等,但是並沒限制通信使用的傳輸協議。這里,我將分別介紹利用TCP和UDP傳輸協議來實現的809協議對接的方法。

2.TCPUDP的介紹

TCP協議和UDP協議均是面向傳輸層的一種協議。而我們常說的HTTP協議則是面向應用層的一種協議。

我們常說的TCP/IP協議,則是一個協議簇,其中TCP、UDP協議均包含於這個協議簇。至於這個協議為什么叫TCP/IP,是因為TCP和IP協議是其中最重要的兩個協議。

2.1TCP協議介紹

TCP(Transmission Control Protocol,傳輸控制協議)是面向連接的協議,也就是說,在收發數據前,必須和對方建立可靠的連接。一個TCP連接必須要經過三次“對話”才能建立起來,其中的過程非常復雜,只簡單的描述下這三次對話的簡單過程:主機A向主機B發出連接請求數據包:“我想給你發數據,可以嗎?”,這是第一次對話;主機B向主機A發送同意連接和要求同步(同步就是兩台主機一個在發送,一個在接收,協調工作)的數據包:“可以,你什么時候發?”,這是第二次對話;主機A再發出一個數據包確認主機B的要求同步:“我現在就發,你接着吧!”,這是第三次對話。三次“對話”的目的是使數據包的發送和接收同步,經過三次“對話”之后,主機A才向主機B正式發送數據。

總結上面這段話,主要包含了兩個關鍵詞:三次握手、可靠連接:     

     

如建立連接一般復雜,TCP協議斷開也相對復雜,需要進行四次揮手:

             

2.2UDP協議介紹

UDP(User Data Protocol),即用戶數據報協議,其包含的特征主要如下:
a.UDP是一個非連接的協議,傳輸數據之前,源端和終端不建立連接,當它想傳送時就簡單地去抓取來自應用程序的數據,並盡可能快地把它扔到網絡上。在發送端,UDP傳送數據的速度僅僅是受應用程序生成數據的速度、計算機的能力和傳輸帶寬的限制;在接收端,UDP把每個消息段放在隊列中,應用程序每次從隊列中讀一個消息段。
b.由於傳輸數據不建立連接,因此也就不需要維護連接狀態,包括收發狀態等,因此一台服務機可同時向多個客戶機傳輸相同的消息。
c.UDP信息包的標題很短,只有8個字節,相對於TCP的20個字節信息包的額外開銷很小。
d.吞吐量不受擁擠控制算法的調節,只受應用軟件生成數據的速率、傳輸帶寬、源端和終端主機性能的限制。
e.UDP使用盡最大努力交付,即不保證可靠交付,因此主機不需要維持復雜的鏈接狀態表(這里面有許多參數)。
f.UDP是面向報文的。發送方的UDP對應用程序交下來的報文,在添加首部后就向下交付給IP層。既不拆分,也不合並,而是保留這些報文的邊界,因此,應用程序需要選擇合適的報文大小。
我們經常使用“ping”命令來測試兩台主機之間TCP/IP通信是否正常,其實“ping”命令的原理就是向對方主機發送UDP數據包,然后對方主機確認收到數據包,如果數據包是否到達的消息及時反饋回來,那么網絡就是通的。

總結UDP協議,其最大的特點是其無連接性,支持廣播通信(支持一對多、多對多通信)。廣播地址(Broadcast Address)是專門用於同時向網絡中所有工作站進行發送的一個地址。在使用TCP/IP 協議的網絡中,主機標識段host ID 為全1 的IP 地址為廣播地址,廣播的分組傳送給host ID段所涉及的所有計算機。例如,對於10.1.1.0 (255.255.255.0 )網段,其廣播地址為10.1.1.255 (255 即為2 進制的11111111 ),當發出一個目的地址為10.1.1.255 的分組(封包)時,它將被分發給該網段上的所有計算機。

      

2.3協議對比

TCP與UDP區別總結:
 a.TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發送數據之前不需要建立連接。
 b.TCP提供可靠的服務。也就是說,通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序到達;UDP盡最大努力交付,即不保證可靠交付 。
 c.TCP面向字節流,實際上是TCP把數據看成一連串無結構的字節流;UDP是面向報文的
UDP沒有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如IP電話,實時視頻會議等)。
d.每一條TCP連接只能是點到點的;UDP支持一對一,一對多,多對一和多對多的交互通信 。
e.TCP首部開銷20字節;UDP的首部開銷小,只有8個字節。
f.TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道。

3.Socket編程

3.1基本概念

網絡上的兩個程序通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。

建立網絡通信連接至少要一對端口號(socket)。socket本質是編程接口(API),對TCP/IP的封裝,TCP/IP也要提供可供程序員做網絡開發所用的接口,這就是Socket編程接口;HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網絡通信的能力。

目前各大主流語言基本都支持socket編程。C#基於socket封裝了TCPClient以及UDPClient類,使得socket編程更加簡單。

在進行網絡編程時,我們常常見到同步(Sync)/異步(Async),阻塞(Block)/非阻塞(Unblock)四種調用方式:
同步:所謂同步,就是在發出一個功能調用時,在沒有得到結果之前,該調用就不返回。也就是必須一件一件事做,等前一件做完了才能做下一件事。例如普通B/S模式(同步):提交請求->等待服務器處理->處理完畢返回 這個期間客戶端瀏覽器不能干任何事。

異步:異步的概念和同步相對。當一個異步過程調用發出后,調用者不能立刻得到結果。實際處理這個調用的部件在完成后,通過狀態、通知和回調來通知調用者。 例如 ajax請求(異步): 請求通過事件觸發->服務器處理(這是瀏覽器仍然可以作其他事情)->處理完畢。

阻塞:阻塞調用是指調用結果返回之前,當前線程會被掛起(線程進入非可執行狀態,在這個狀態下,cpu不會給線程分配時間片,即線程暫停運行)。函數只有在得到結果之后才會返回。有人也許會把阻塞調用和同步調用等同起來,實際上他是不同的。對於同步調用來說,很多時候當前線程還是激活的,只是從邏輯上當前函數沒有返回而已。 例如,我們在socket中調用recv函數,如果緩沖區中沒有數據,這個函數就會一直等待,直到有數據才返回。而此時,當前線程還會繼續處理各種各樣的消息。

非阻塞:非阻塞和阻塞的概念相對應,指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回。
對象的阻塞模式和阻塞函數調用:
對象是否處於阻塞模式和函數是不是阻塞調用有很強的相關性,但是並不是一一對應的。阻塞對象上可以有非阻塞的調用方式,我們可以通過一定的API去輪詢狀 態,在適當的時候調用阻塞函數,就可以避免阻塞。而對於非阻塞對象,調用特殊的函數也可以進入阻塞調用。函數select就是這樣的一個例子。

總結為:

a.同步,就是我調用一個功能,該功能沒有結束前,我死等結果。

b.異步,就是我調用一個功能,不需要知道該功能結果,該功能有結果后通知我(回調通知)。

c.阻塞,就是調用我(函數),我(函數)沒有接收完數據或者沒有得到結果之前,我不會返回。

d.非阻塞,就是調用我(函數),我(函數)立即返回,通過select通知調用者。

3.2同步和異步的實現

3.2.1阻塞通信

  

3.2.2非阻塞通信

實現非阻塞通信有兩種方式,一種是利用異步方式,另一種使用多線程方式實現。兩者的原理也是各不相同:

a.線程本質上是進程中一段並發運行的代碼,所以線程需要操作系統投入CPU資源來運行和調度;

b.異步本質上是計算機硬件功能,其操作無須消耗CPU時間的I/O操作;

編寫異步操作的復雜程度較高,程序主要使用回調方式進行處理,處理函數可以不必使用共享變量;

 c.多線程是順序執行,編程簡單。但是線程的使用(濫用)會給系統帶來上下文切換的額外負擔。並且線程間的共享變量可能造成死鎖的出現。

 當需要執行I/O操作時,使用異步操作比使用線程+同步 I/O操作更合適。I/O操作不僅包括了直接的文件、網絡的讀寫,還包括數據庫操作、Web Service、HttpRequest以及.net Remoting 等跨進程的調用。

       線程適用那種需要長時間CPU運算的場合,例如耗時較長的圖形處理和算法執行。

3.2.2.1多線程實現

    

3.2.2.2異步實現

   

4.809協議對接的實現

  

4.1TCP協議對接(部分)

由於TCP是長連接,所以這里需要用非阻塞方式通信,選擇多線程方法解決:

  

4.2UDP協議對接(部分)

  UDP不需保持連接狀態,所以監聽端口完成操作即可,由於接受消息后操作基本不耗時,所以沒有啟用多線程:

 

4.3809協議解析的實現(部分)

  

5.總結

在研究生期間時,研究過一段時間的socket通信。當時對P2P模式,以及UDP打洞都還挺感興趣。以后有機會和大家在一起探討。

 

                               -----歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/

                                                                                如果您覺得本文確實幫助了您,可以微信掃一掃,進行小額的打賞和鼓勵,謝謝 ^_^

                                      

 


免責聲明!

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



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