幾天前在博問中看到一個C# Socket問題就想到筆者年做的一個省級交通流量接收服務器項目當時的基本求如下
接收自動觀測設備通過無線網卡Internet和Socket上報的交通量數據包 全年*運行的自動觀測設備分鐘上報一次觀測數據每筆記錄約K大小 規劃全省將有個左右的自動觀測設備(截止年月還只有個)
當時VS才發布年多筆者也是接觸C#不久於是Google了國內國外網希望找點應用C#解決Socket通信問題的思路和代碼最後找到了兩篇幫助最大的文章一篇是國人寫的Socket接收器框架應用了獨立的客戶端Socket會話(Session)概念給筆者提供了一個接收服務器的總體框架思路另一篇是美國人寫的提出了多線程分段接收數據包的技術方案描述了多線程異步Socket的許多實現細節該文堅定了筆者采用多線程和異步方式處理Socket接收器的技術路線
具體實現和測試時筆者還發現在Internet環境下的Socket應用中需要系統有極強的容錯能力沒有辦法控制異常就必須允許它們存在(附加源代碼中可以看到try{}catch{}語句較多)對此筆者設計了一個專門的檢查和清理線程完成無效或超時會話的清除和資源釋放工作
依稀記得國內框架作者的名稱空間有ibm認為是IBM公司職員通過郵件後才知道其人在深圳筆者向他請教了幾個問題相互探討了幾個技術關鍵點可惜現在再去找已經查不到原文和郵件了只好借此機會將本文獻給這兩個素未謀面的技術高人和同行也盼望拙文或源碼能給讀者一點有用的啟發和幫助
主要技術思路
整個系統由三個核心線程組成並由NET線程池統一管理
偵聽客戶端連接請求線程ListenClientRequest()循環偵聽客戶端連接請求如果有檢測該客戶端IP看是否是同一觀測設備然後建立一個客戶端TSession對象並通過Socket異步調用方法BeginReceive()接收數據包EndReceive()處理數據包 數據包處理線程HandleDatagrams()循環檢測數據包隊列_datagramQueue完成數據包解析判斷類型存儲等工作 客戶端狀態檢測線程CheckClientState()循環檢查客戶端會話表_sessionTable判斷會話對象是否有效設置超時會話關閉標志清楚無效會話對象及釋放其資源 主要類簡介
系統主要由個類組成
TDatagramReceiver(數據包接收服務器)系統的核心進程類建立Socket連接處理與存儲數據包清理系統資源該類提供全部的public屬性和方法 TSession(客戶端會話)由每個客戶端的Socket對象組成有自己的數據緩沖區清理線程根據該對象的最近會話時間判斷是否超時 TDatagram(數據包類)判
斷數據包類別解析數據包
關鍵函數和代碼
下面簡介核心類TDatagramReceiver的關鍵實現代碼
系統啟動
系統啟動方法StartReceiver()首先清理資源創建數據庫連接初始化若干計數值然後創建服務器端偵聽Socket對象最後調用靜態方法ThreadPoolQueueUserWorkItem()在線程池中創建個核心處理線程
Code
///
/// 啟動接收器
///
public bool StartReceiver()
{
try
{
_stopReceiver = true;
thisClose();
if (!thisConnectDatabase()) return false;
_clientCount = ;
_datagramQueueCount = ;
_datagramCount = ;
_errorDatagramCount = ;
_exceptionCount = ;
_sessionTable = new Hashtable(_maxAllowClientCount);
_datagramQueue = new Queue<TDatagram>(_maxAllowDat
From:http://tw.wingwit.com/Article/program/net/201311/13031.html