WinCE Heartbeat Message的实现
Heartbeat Message通常被稱為心跳幀,用于遠程設備,告訴接收者我還活著。一般Heartbeat message會每隔一段時間發送一次,時間間隔根據需要來定。如果接收者一段時間內沒有接收到設備的Heartbeat message,就會知道該設備可能被關閉或者出了問題。
?
一般Heartbeat message都是基于UDP的廣播,根據具體的環境和需求,Heartbeat message中可以包含多種信息,用于反映設備的基本信息和運行狀態。這里給一個Heartbeat Message網絡數據包的格式,如下:
?
假設HeartBeat Message網絡數據包由包頭(Standard Message Header)和數據(Message Data)兩部分組成,這樣看來,上圖描述的數據包格式不只用于HeartBeat Message,也可以用于其它類型的網絡數據傳輸,當然這里只是介紹HeartBeat Message,先來介紹一下包頭(Standard Message Header),定義如下:
?
Src Hw Type: Byte 0-1
源設備的設備類型,一般大型系統中可能有不同類型的設備,比如網絡采集設備,網絡顯示終端,網絡控制設備等。這兩個Byte用于標示該設備的設備類型。
?
Src Dev Id: Byte 3-4
源設備的設備ID,系統中每個網絡設備都有一個唯一的ID號,這兩個Byte用于標示該設備的ID號。
?
Dst Hw Type: Byte 5-6
目的設備的設備類型,對于Heartbeat Message來說,這兩個Byte可以是0xFF,0xFF。
?
Dst Dev Id: Byte 8-9
目的設備的設備ID,除非你要將Heartbeat Message發動到指定的設備,否則這兩個Byte應該是0xFF, 0xFF。
?
Prot Ver: Byte 10-11
通訊協議的版本,這2個Byte指數據包的格式,以后可能會升級,所以要包含當前協議的版本,或者說當前數據包格式的版本信息。
?
Msg Id: Byte 12-13
這里只發送數據包中的消息的ID,你可能不只發送Heartbeat Message,可能還要發送其他的Message,每一種Message有一個ID號來標示,比如對于Heartbeat Message,這兩個Byte可以是0x5010,當然也可以定義為其他。
?
Msg Type: Byte 14-15
消息的類型,對于一個復雜的系統,可能有很多種類型的消息,比如Command Message, Error Message, Response Message,當然Heartbeat Message也是一種,可以為Heartbeat Message的類型定義為0x0005。
?
Connection Type: Byte 16
連接類型,表示當前消息基于Broadcast,還是point to point,一般Heartbeat Message都是Broadcast的。
?
Msg Priority: Byte 17
消息的優先級,這里可以為消息定義不同的優先級,接收消息的設備可能同時接收很多個來自不同設備的網絡消息,可以按照優先級來處理,這里Heartbeat Message的優先級可定義為Low或者Normal。
?
Reserved: Byte 18-21
預留4個Byte以后擴展或者做特殊用途。
?
Msg Length: Byte 22-23
描述后面消息的長度。
?
前面介紹了數據包包頭,下面介紹一下數據包中的數據部分,HeartBeat Message的數據部分結構,如圖:
?
?
MAC Address: Byte 24-29
設備的MAC地址。
?
BootLoader Ver: Byte 30-31
設備的Bootloader的版本號
?
Application Ver: Byte 32-33
設備的軟件版本號
?
Config Ver: Byte 34-35
設備的配置文件或者數據庫的版本號
?
Running Status: Byte 36
設備的運行狀態,是Full-run狀態,還是某一種低功耗運行狀態。
?
Power Status: Byte 37
設備的電源狀態,可能包含多種電源輸入,比如3.3V,5V,+/-12V等,可以每個bit表示一種電源輸入的狀態,是否所有電源輸入正常。
?
Temperature Status: Byte 38
設備的溫度狀態,設備中可能包含多個溫度傳感器,每個Bit表示一路溫度監測是否正常。
?
Extended Info: Byte 39-42
擴展信息,用于傳輸一些額外的信息。
?
?
前面把Heartbeat Message的格式介紹完了,然后就是發送該數據包。在WinCE下很簡單,就是一個socket的網絡廣播通訊,首先include “winsock2.h”頭文件,連接Ws2.lib靜態庫,剩下的就是socket編程了,代碼如下:
?
?
char?c_name[255];
int?i_brdcast, i_blockMode;
int?serverSock;
LPHOSTENT lpAddr;
in_addr ipAddr, brdAddr;
WSADATA wsaData;
WORD wVersion;
BOOL b_Ret;
?
struct?HeartBeat* pHeartbeat, Heartbeat_Data;
struct?sockaddr_in serverAddr;
?
b_Ret = FALSE;
pHeartbeat = &Heartbeat_Data;
// Windows Socket Initialization
wVersion = MAKEWORD(2, 2);
wsaStatus = WSAStartup(wVersion, &wsaData);
?
// Initialize socket addr structure
memset((char*)&serverAddr, 0,?sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(SOCKET_PORT);
?
// Create socket
serverSock = socket(AF_INET, SOCK_DGRAM, 0);
if?(serverSock != INVALID_SOCKET)
{??????????
??????gethostname(c_name,?sizeof(c_name));
??????lpAddr = gethostbyname(c_name);
??????ipAddr = *(struct?in_addr FAR*)(lpAddr->h_addr);
?????
??????// Initialize the broadcast address that depends on your network
??????brd_addr.sin_addr.S_un.S_un_b.s_b1 = ipAddr.S_un.S_un_b.s_b1;
??????brd_addr.sin_addr.S_un.S_un_b.s_b2 = ipAddr.S_un.S_un_b.s_b2;
??????brd_addr.sin_addr.S_un.S_un_b.s_b3 = 0xFF;
??????brd_addr.sin_addr.S_un.S_un_b.s_b4 = 0xFF;
?
??????// bind socket
??????if?(bind(serverSock, (LPSOCKADDR)&serverAddr,?sizeof(struct?sockaddr)) != SOCKET_ERROR)
??????{
????????????// support broadcast
????????????i_brdcast = 1;
????????????if?(setsockopt(serverSock, SOL_SOCKET, SO_BROADCAST, (char*)&i_brdcast,sizeof(i_brdcast)) != SOCKET_ERROR)
????????????{
??????????????????// set socket block mode
??????????????????i_blockMode = 0;
?????????????????if?(ioctlsocket(serverSock, FIONBIO, (u_long*)&i_blockMode) != SOCKET_ERROR)
??????????????????{
????????????????????????b_Ret = TRUE;
??????????????????}
????????????}
??????}
}
?
if?(b_Ret == TRUE)
{
??????// Initialize the Heartbeat Message buffer
??????pHeartbeat->Mac = ;
??????pHeartbeat->Bl_Ver = ;
??????pHeartbeat->Cfg_Ver = ;
??????pHeartbeat->App_Ver = ;
??????pHeartbeat->RunStatus = ;
??????pHeartbeat->PowerStatus = ;
??????pHeartbeat->TempStatus = ;
?
?
??????while (1)
??????{????
????????????sendto(serverSock, (char*)pHeartbeat, HEARTBEAT_LEN, 0,( LPSOCKADDR)&brdAddr,?sizeof(brdAddr));
????????????// Sleep 10 seconds
????????????Sleep(10000);
??????}
}
?
該代碼是隨手寫的,沒有調試,編譯不過很正常,實際上這里只是給個例子。對于上面的代碼多說兩句,建議發送Heartbeat Message單獨啟動一個線程來做,也可以啟動一個Timer來做。還有就是廣播地址可以是255.255.255.255,也可以是分段廣播,比如192.255.255.255或者192.168.255.255。使用什么樣的廣播地址取決于你的系統,比如你可能只希望在當前網段廣播Heartbeat Message,不要影響到其他的網段,那就可以根據具體情況來設置廣播地址。
總結
以上是生活随笔為你收集整理的WinCE Heartbeat Message的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WinCE文件目录定制及内存调整
- 下一篇: wince国际化语言支持