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