基于Flash的遠(yuǎn)程工業(yè)監(jiān)控系統(tǒng)設(shè)計(jì)
3.2.1 1PAC服務(wù)端程序?qū)崿F(xiàn)
PAC服務(wù)端的實(shí)現(xiàn)主要分為通過Socket與上位機(jī)的通信和通過串口服務(wù)與外圍設(shè)備的通信兩大部分。
通過Socket與上位機(jī)的通信主要分為監(jiān)聽和連接。在監(jiān)聽狀態(tài)下負(fù)責(zé)監(jiān)聽客戶端的請(qǐng)求連接,并負(fù)責(zé)接受此連接。本系統(tǒng)PAC端設(shè)計(jì)監(jiān)聽類為ServerListen,監(jiān)聽類首先通過int bind(int sockfd,struct sockaddr*my_addr,int addrten)綁定了本地的502端口,然后通過函數(shù)int listen (int sockfd,intbacklog)將客戶端的連接請(qǐng)求放入隊(duì)列中等待,直到函數(shù)intaccept(int sockfd,void*addr,int*addrlen)處理它,然后返回一個(gè)全新的套接字文件來描述此單個(gè)連接。這樣,對(duì)于同一個(gè)連接就有兩個(gè)文件描述符,原先的一個(gè)文件描述符正在監(jiān)聽你指定的端口,新的文件描述符可以用來調(diào)用send()和recv()。在連接狀態(tài)下負(fù)責(zé)與客戶端進(jìn)行數(shù)據(jù)的接收和發(fā)送,通過數(shù)據(jù)傳輸類Server Custom來實(shí)現(xiàn)。在此類中利用int send(SOCKETs,const char FAR*buf,int len,int flags)函數(shù)將PAC服務(wù)端的數(shù)據(jù)發(fā)送到客戶端,如果網(wǎng)絡(luò)發(fā)生故障或待發(fā)送數(shù)據(jù)的長(zhǎng)度len小于當(dāng)前程序要發(fā)送數(shù)據(jù)的緩沖區(qū)的長(zhǎng)度,則返回SOCKET_ERROR,利用int recv(SOCKETs,char FAR* buf,int len,int flags)從客戶端接收數(shù)據(jù)。函數(shù)先等待s的發(fā)送緩沖中的數(shù)據(jù)被協(xié)議傳送完畢,如果協(xié)議在傳送s的發(fā)送緩沖中的數(shù)據(jù)時(shí)出現(xiàn)網(wǎng)絡(luò)錯(cuò)誤,則函數(shù)返回SOCKET_ERROR錯(cuò)誤,如果s的發(fā)送緩沖中沒有數(shù)據(jù)或者數(shù)據(jù)被協(xié)議成功發(fā)送完畢后,函數(shù)先檢查套接字s的接收緩沖區(qū),如果s的接收緩沖區(qū)中沒有數(shù)據(jù)或者協(xié)議正在接收數(shù)據(jù),那么函數(shù)就一直等待,直到協(xié)議把數(shù)據(jù)接收完畢。
對(duì)于外圍設(shè)備進(jìn)行通信主要是通過串口服務(wù),首先調(diào)用自己定義的COM口初始化函數(shù)InstallCom將端口初始化,然后通過build_REQ_Read函數(shù)實(shí)現(xiàn)根據(jù)ModBusRtu通訊協(xié)議將COM口讀取的外圍設(shè)備的數(shù)據(jù)放入自定義的數(shù)組中,并通過CRC16_modbus進(jìn)行CRC校驗(yàn)。接收的數(shù)據(jù)正確,則通過analyse_Read_Result分析從串口讀取的數(shù)據(jù),并將讀取的數(shù)據(jù)位存放到Share_Mem[MaxShareMemNum]數(shù)組中。然后將Share_Mem數(shù)組作為REMOTCP_ModServer_Create參數(shù)與上位機(jī)進(jìn)行通訊。對(duì)外圍設(shè)備發(fā)送指令,則是通過函數(shù)SendCommand選擇控制對(duì)象的COM后,將指令發(fā)送到外圍設(shè)備,外圍設(shè)備接收到指令后動(dòng)作。
3.2.2 客戶端程序與PAC服務(wù)端通訊的實(shí)現(xiàn)
客戶端的實(shí)現(xiàn)主要分為3個(gè)部分:通過Flash的Socket與PAC服務(wù)端的數(shù)據(jù)交互,將接收的數(shù)據(jù)在頁(yè)面上動(dòng)態(tài)顯示和將獲取的數(shù)據(jù)實(shí)時(shí)存入到數(shù)據(jù)庫(kù),實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)庫(kù)的歷史存儲(chǔ)功能。
客戶端Flash與PAC服務(wù)端的數(shù)據(jù)交互主要是通過Socket進(jìn)行的。首先定義Socket,利用connect連接PAC服務(wù)器的地址和端口號(hào)502,利用mysocket.a(chǎn)ddEventListener(Event.CONNECT,OnConnect)監(jiān)聽是否已建立連接,利用mysocket.a(chǎn)ddEventListener (IOErrorEvent.IO_ ERROR,ioErrorHandler)來監(jiān)聽連接過程中出現(xiàn)的錯(cuò)誤,利用mysoeket.a(chǎn)ddEventListener(Event.CLOSE,OnClose)監(jiān)聽連接是否關(guān)閉,利用mysocket.a(chǎn)ddEventListener(ProgressEvent.SOCKET DATA,receivedata) 中的mysoeket.readMultiByte(mysocket.bytesAvailabl e,“utf8”)接收PAC服務(wù)端發(fā)送過來的數(shù)據(jù)。添加控制功能則是通過flash頁(yè)面中的控件的觸發(fā)事件來完成。在觸發(fā)事件中添加mysocket. writeUTFBytes(data),并調(diào)用mysocket.flush()方法將觸發(fā)的事件發(fā)送出去,從而完成了與服務(wù)端的數(shù)據(jù)交換。
在發(fā)送與接收數(shù)據(jù)的過程中由于遵循的為Modbus/TCP協(xié)議,發(fā)送和接收的數(shù)據(jù)要遵循Modbus標(biāo)準(zhǔn)的數(shù)據(jù)幀格式,因此需要根據(jù)Modbus協(xié)議的標(biāo)準(zhǔn)格式對(duì)所接收和發(fā)送的數(shù)據(jù)幀進(jìn)行轉(zhuǎn)化。在接收的數(shù)據(jù)中,要對(duì)接收的數(shù)據(jù)進(jìn)行分析,根據(jù)自己的定義,將地址與監(jiān)控終端的信息取出,并轉(zhuǎn)換為String類型,在頁(yè)面上對(duì)應(yīng)顯示。
3.2.3 客戶端與數(shù)據(jù)庫(kù)的交互
對(duì)采集來的數(shù)據(jù)除了在頁(yè)面上顯示,需要存入數(shù)據(jù)庫(kù)作為歷史備份。客戶端Flash與Oracle數(shù)據(jù)庫(kù)無法直接交互,可以通過服務(wù)器端技術(shù)連接數(shù)據(jù)庫(kù),這3種連接方式為:HttpService、WebService和RemoteObject。3種通訊方式比較如表1所示。本文引用地址:http://butianyuan.cn/article/160350.htm
從上表中可以看出,前兩種通信數(shù)據(jù)量較小,要傳輸大量的數(shù)據(jù)或是實(shí)現(xiàn)不同對(duì)象的序列化傳輸,需要利用高效的傳輸協(xié)議AMF(Aetion Script Message Format)來代替SOAP協(xié)議傳輸?shù)姆桨浮?br /> 開源項(xiàng)目FluorineFx就是專門針對(duì).net平臺(tái)與Flex通信提供的AMF協(xié)議通信網(wǎng)關(guān),筆者可以通過FluorineFx方便地完成與.net的通信。
評(píng)論