TCP/UDP簡易通訊框架源碼,支持輕鬆管理多個TCP服務端(客戶端)、UDP客戶端

目錄html

說明git

以前有好幾篇博客在講TCP/UDP通訊方面的內容,也有作過一些Demo(包括整理出來的、可供學習使用的簡單通訊框架)。具體能夠參見如下博客:github

http://www.cnblogs.com/xiaozhi_5638/p/4244797.html(清晰易懂TCP通訊原理解析)服務器

http://www.cnblogs.com/xiaozhi_5638/p/3290283.html(基於泵的TCP通訊過程創建)框架

http://www.cnblogs.com/xiaozhi_5638/p/3169641.html(基於泵的UDP通訊過程創建)學習

http://www.cnblogs.com/xiaozhi_5638/p/4528551.html(泵結構在系統中的做用)測試

能夠看出,不少博客一直在強調「泵」(循環結構)在各個場合中的做用,如有不清楚泵結構的朋友,能夠參見這篇博客「代碼中的泵」。今天此次博客的重點並非講泵結構在通訊過程當中的應用,而是講如何在同一進程中輕鬆快捷地建立多個TCP服務端(綁定多個Port)、多個TCP客戶端(隨意鏈接指定服務端)、多個UDP客戶端(綁定多個Port),同時可以進行統一管理、訪問。3d

在TCP通訊開發過程當中,常常會出現一個程序須要監聽多個Port,或者一個程序須要鏈接多個TCP服務器(本人實際項目中遇到過),那麼如何統1、方便管理建立的多個Socket呢?代理

如上圖左邊所示,一個程序須要同時訪問兩個Server,那麼它至少要同時保持兩個Socket鏈接。同理,一個服務程序極可能同時監聽多個Port,須要管理多個偵聽Socket。在UDP通訊系統中(上圖右邊),一個程序也可能須要監聽多個Port,同時接收多個Port上的數據。那麼本文提供了一套能夠輕鬆管理這些多個Socket的方案。htm

 

TCP/UDP通訊主要結構

TCP服務端

一個TCP服務端主要包含兩個結構:一個是Socket偵聽循環(Socket偵聽泵),一個即是數據接收循環(數據接收泵)。前者主要負責處理Socket連入請求,後者負責接收對應客戶端發來的數據。下圖顯示的是一個TCP服務端包含的主要構造:

TCP客戶端

一個TCP客戶端主要包含一個結構:數據接收循環(數據接收泵)。客戶端Socket連入服務器成功後,便須要開啓數據接收循環,用於接收服務端發來的數據。下圖顯示的是一個TCP客戶端包含的主要構造:

UDP客戶端

一個UDP客戶端主要包含一個結構:數據接收循環(數據接收泵)。客戶端綁定本地Port成功後,便須要開啓數據接收循環,用於接收來自綁定端口的數據。下圖顯示的是一個UDP客戶端包含的主要構造:

注:

雖然UDP通訊中的每一個終端都是平等的(不存在主動連入和被動連入),但仍是習慣上稱每一個終端爲Client。雖然它包含的主要結構和TCP客戶端相似(都只有一個數據接收循環),可是在TCP中,客戶端Socket須要提早Connect到服務器,而一般狀況下,UDP須要提早綁定本地端口。

 

管理多個Socket的解決方案

這裏說到的Socket,在TCP服務端中指的是偵聽Socket,在TCP客戶端中指的是與服務端創建鏈接的Socket,而在UDP客戶端中指的是綁定本地端口的Socket。這些Socket均可以存在多個,TCP服務端中能夠有多個Socket偵聽不一樣的Port,TCP客戶端能夠有多個Socket與不一樣的服務端創建鏈接,而UDP客戶端中則能夠有多個Socket綁定不一樣的端口。那麼如何管理多個Socket呢?

答案其實很簡單,能夠將它們放進一個容器,統一經過容器管理、訪問。那麼怎樣區分不一樣的Socket呢?咱們能夠給每一個Socket加一個惟一標示(ID)。以後每次訪問,均經過ID區分,只要給定ID,其他的操做均相同。這樣一來,TCP服務端、TCP客戶端以及UDP客戶端的構造能夠變成:

多個TCPServer:

多個TCPClient

多個UDPClient

每次訪問,好比TCP服務端開啓偵聽、註冊事件以及主動調用發送數據的API時,都可以經過容器代理進行操做,只須要給出指定的ID進行區分便可。

 

框架中TCP部分的用法

TCP服務端

框架公開了TCPServerManager、TCPEndPoint兩個類型,前者主要負責代理操做的功能,全部對服務端的操做均經過它來完成;後者對應每一個鏈接進來的客戶端。

1)建立服務器

以後即可以使用manager操做建立好的服務器。注意若是這裏已經存在ID爲RegisterServer的服務器的話,manager就指代已經建立好的服務器。咱們還能夠建立第二服務器:

以上,只要給定的ID不一樣便可。

2)啓動服務器

3)註冊事件

以上分別註冊客戶端鏈接、斷開以及發送消息的事件,以後即可以在事件處理方法中處理消息。

4)消息處理

當客戶端發送消息時,系統會激發TCPMessageReceived事件,咱們在事件處理程序中能夠解析、處理消息:

在消息處理這塊,框架簡單地定義了一個「協議」:消息類型+消息正文。若是你以爲不夠,徹底能夠在args.Data中再定義本身的協議。客戶端上線、下線處理方式相似。這裏再也不贅述。

TCP客戶端

框架公開了TCPClientManager類型,它主要負責代理操做的功能,全部對客戶端的操做均經過它來完成。

1)建立客戶端

以上建立了一個TCP客戶端。若是給定的ID已存在,那麼manager指代已經存在的客戶端。同理,咱們能夠建立第二個客戶端:

以上,只要給定的ID不一樣便可。

2)鏈接服務器

3)註冊事件

以上註冊消息事件,當收到服務端消息時會激發TCPMessageReceived事件。

4)消息處理

TCP客戶端消息處理這塊參見TCP服務端。原理相似。

 

框架中UDP部分的用法

UDP客戶端

框架公開了UDPClientManager類型,主要負責代理操做的功能,對UDP客戶端的全部操做均由它來完成。

1)建立客戶端

以上建立了一個UDP客戶端。若是給定的ID已存在,那麼manager指代的是已經存在的UDP客戶端。同理,咱們能夠建立第二個UDP客戶端:

以上,只要給定的ID不存在便可。

2)監聽端口

以上建立了兩個不一樣的UDP客戶端,分別監聽不一樣的Port,接收不一樣的數據。

3)註冊事件

以上註冊了消息事件,當端口上有數據收到時會激發UDPMessageReceived事件。

4)消息處理

當UDP客戶但收到消息時,系統會激發UDPMessageReceived事件,咱們能夠在事件處理程序中解析、處理消息:

注意UDP這塊處理消息有一點與TCP不一樣,args參數中是以RemoteIP和RemotePort來代表消息發送方的信息,而TCP處理消息時,args參數中以TCPEndPoint來表明消息發送方的信息,後者包含的信息更全(不僅有RemoteIP和RemotePort,具體參見源碼)。

在消息處理這塊,框架簡單地定義了一個「協議」:消息類型+消息正文。若是你以爲不夠,徹底能夠在args.Data中再定義本身的協議。

 

框架源碼結構

.NET4.0  VS2010

對外公開的有TCPServerManager、TCPClientManager、TCPEndPoint、UDPClientManager以及Msg枚舉類型。

 

補充說明

  • TCP部分已解決沾包問題,附帶心跳檢測功能(有待完善);
  • 框架默認採用了一個簡單的協議,用以區分發送消息的類型。咱們在使用過程當中,徹底能夠自定義應用層協議(再封裝一層),並在收到數據後解析;
  • TCP服務端的在線列表須要本身人工維護(上下線);收到的消息數據都是byte[]類型,須要本身解析;並且不能註冊本身想要的消息(必須所有接收)。因爲我司主要開發局域網內網系統,對鏈接數量要求不是很高,我司實際使用中的通訊框架經實體機房測試,鏈接數在400+,系統運行穩定。TCP部分發送3G大文件,不會出現內存異常等問題。
  • 此次也是爲了驗證多個Socket管理的方案,因此纔出了這個框架,因爲時間倉促,因此僅供學習使用。如有人要應用到實際項目中去,可能須要修改完善一些地方,由於我並無徹底測試。

源碼地址

源碼中帶有兩個Demo。

github:https://github.com/sherlockchou86/TJSYXYCommunication

rar文件直接下載:http://files.cnblogs.com/files/xiaozhi_5638/TJSYXY.Communication.rar

相關文章
相關標籤/搜索