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


目錄

說明

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

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),同時能夠進行統一管理、訪問。

在TCP通信開發過程中,經常會出現一個程序需要監聽多個Port,或者一個程序需要連接多個TCP服務器(本人實際項目中遇到過),那么如何統一、方便管理創建的多個Socket呢?

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

 

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


免責聲明!

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



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