摘要本文主要論述了遠程水位監測系統的通信幀的格式。以及對不同的通信幀的發送和接收的不同處理。水庫水位監測系統軟件作為客戶端,遠程測控系統作為服務器端,通過網絡傳遞信息,通過WinSock來實現網絡之間的鏈接和數據交換。
關鍵詞水位監測系統 通信幀 類 數據通信
中圖分類號:TP39文獻標識碼:A
1 通信幀的格式
Windows MFC(Microsoft Foundation Class)將有關SOCKET的操作封裝到一個類——Csocket中。我們在進行網絡通訊時,又從Csocket中派生另外兩個類,CClientSocket和ClientSocket,在類中定義了一個區分標志位flag。
客戶端的行為封裝在類CclientSocket中,在其中針對不同的信息幀定義了不同的發送函數和接收函數,因此,在水庫監測系統軟件(客戶端)中,進行數據通信時,只需調用函數:收信息幀函數和發信息幀函數。而且,為了保持模塊的獨立性,我們將有關信息幀封裝到一個類CMsg中下面我們要對幀的格式加以描述。當進行水庫水位的遠程測量時發送通信幀的格式如下:
接受通信幀的格式如下:
各個變量的含義為:
int flag;//套接字的值(區分標志位)
BOOL m_bClose; //套接字是否關閉
Int m_strTableName;//測量數據寫入到數據庫的表中(用m_strTableName的整數值代表)
Cstring m_strSendText;//發送的字符串
Cstring m_strText;//接收字符串
int single發送的信息幀是字符類型還是數據類型
float bufferSend[40];//發送測量數據的緩沖區
2 通信幀的類型
根據各個標志位具體值的不同,通信幀的共有二種不同的類型:字符類型、數據類型。針對不同的信息幀都有不同的發送函數。字符類型通信幀又可分為關閉型和非關閉型,通信的信息都是字符串。
數據類型通信幀包含的信息是一組數據。當服務器端和客戶端連接成功時,客戶端向服務器度端發出一個非關閉型字符型信息幀,通知對方連接成功。在測量水庫水位時,每測量完一個測量點,將測得的數據轉換為字符型,通過一個字符型通信幀發向服務器端,并在服務器端顯示出來,以達到實時性顯示的要求。在巡測水庫水位時,即對水庫的各個斷面的測量點都測完,并存儲到本地數據文件中讀出到緩沖區中,用發送消息幀函數發出。
3 服務器端和客戶端通信的實現
有關幀的格式及其初始化封裝在類CMsg中。類CMsg的聲明如下:
class CMsg :public Cobject
{protected:
DECLARE_DYNCREATE(CMsg)
public:
CMsg();
//Attributes
public:
Cstring m_strSendText;// 發送的字符串
Cstring m_strText;// 接收字符串
int m_strTableName;// 測量數據寫入到數據庫的表中(用m_strTableName的整數值代表)
float bufferSend[40];// 發送測量數據的緩沖區
int flag;// 套接字的值(區分標志位)
BOOL m_bClose;// 套接字是否關閉
int single;//該信息包
//Operations
public:
void init();
//Implementation
public:
Void initXunceMessage(Cstring message);
Void initExitMessage(Cstring message);//初始化字符型(關閉)信息幀
Void initComMessage(Cstring message);// 初始化字符型信息幀
Virtual~ CMsg();
Virtual void Serialize(Carhivear);//與進行交互:序列化/反序列化
};
其中有四個初始化幀的函數:
void init();//初始化數據型信息幀
Void initXunceMessage(Cstring message);// 初始化字符型(單個測量點)信息幀
Void initExitMessage(Cstring message);// 初始化字符型(關閉)信息幀
Void initComMessage(Cstring message);// 初始化字符型信息幀
序列化函數通過重載操作符“<<”和“>>”是將一系列CMsg()成員變量變成字節流(序列化Serialize)或者由字符流合成CMsg()成員變量(反序列化Serialize),字節流在檔案類Carchive中,Carchive類相當于Socket文件的CsockeFile的緩沖區。
在與CMsg()中與四個初始化信息幀函數相對應,在類的成員函數中定義了四個發送信息幀函數和一個接收信息幀函數。
接收信息幀函數:void ReceiveMsg(CMsg*pMsg);
發送信息幀函數:void SendinitMsg();
VoidSendXunceMessage(Cstring message);
VoidSendExitMessage(Cstring message);
VoidSendComMessage(Cstring message);
4 查詢、巡測、選測、部分選測功能
客戶端程序中,為了方便用戶對以前的測量結果進行查詢,將每次測得的數據和時間存儲到數據文件和索引文件中。為此定義了索引文件中的數據結構:
Struct TestResultStruct
{time_t time;
LONG Address;}
其中,成員變量time用來存儲測量的時間,存儲每次測量的數據存儲在數據文件中的地址。根據此地址讀取數據。
水庫共有9個斷面,每個斷面包括多個測量點,為了表示多個斷面及斷面中的測量點,在類中定義了屬性成員:
CStringArray WellName;
CObArray WellNameInDuanMian;
CObArray Results;
CObArray ViewSomeOne;
CObArray ViewTestResult;
其中,WellName存放所有測量點的名字,WellNameInDuanMian存放每個斷面的測量點,Results存放測量結果,后面兩個屬性成員當進行查詢時調用,ViewTestResult用來存放從前測量的時間和數據地址,ViewSomeOne存放要查詢的數據,若程序中需要用到某個斷面或測量點,只需給出其數組的下標值即可。
為了實現巡測、選測、部分選測功能,將單個測量點作為測量單位。每測量一個測量點,調用一次測量函數:Void CmeasureDoc::measure(intn);其中,形參n是要測量的測量點的數字號。這樣可以靈活地設置測量的方式,實現測量的多種功能。測量的數據通過調用函數Void CmeasureDoc::measure(int n);將結果存入Results中。這樣,使用巡測、選測、部分選測功能時,只需調用該函數修改Results的值即可。