對應我上一篇文章Vscode mingw下opencv及多線程socket中待完成任務。
工程共享路徑(在code/02文件夾中): https://github.com/AppleCai/Display
一,本周做了變更(版本變更為0.2)
1. 重新設(shè)計了交互協(xié)議。對于接收頭及數(shù)據(jù)的解析使用了狀態(tài)模式設(shè)計。
2. 添加了心跳檢測功能:server每隔1s發(fā)給client,client檢查若5s內(nèi)沒收到則斷開連接。
3. 數(shù)據(jù)/控制/顯示進行了分離設(shè)計,刪除了之前使用線程掛起的方式來實現(xiàn)暫停方式。
4. 代碼進行了重構(gòu),線程由原來的socket和key,還增加了HMI和控制線程。
5. 文件結(jié)構(gòu)變更,拆分為如下6個模塊
socket主要用來傳輸命令和數(shù)據(jù)。
控制模塊主要控制是否正常傳輸數(shù)據(jù),是否傳輸心跳數(shù)據(jù)命令,是否暫停顯示。
key主要掃描s鍵(是否暫停傳輸),j鍵(是否暫停顯示)

協(xié)議.png

簡易圖.png
二,后續(xù)更新版本說明:
之前的2.1/2.2/2.3基本完成,后續(xù)需要完成
2.4 HMI圖片顯示添加ROI區(qū)域顯示張數(shù)及疊加特質(zhì)logo。(使用智能指針及模板類)
2.5 Server端切換到linux系統(tǒng)上。
2.6 重構(gòu)HMI,分離為一個進程。
2.7 添加對圖片的監(jiān)視作用,添加彈窗報警及l(fā)ogDTC記錄。(目的是使用進程間通信和共享內(nèi)存)
2.8 添加守護進程。
2.9 進行性能測試,進行優(yōu)化。
三,頭文件:
#ifndef CTRL_HPP
#define CTRL_HPP
#include "head.hpp"
class key;
class ServerEx;
class HMI;
class display;
class ctrl
{
public:
enum typeMain{transData=1,beat=2,otherType=3};
enum typeSubMain{disable=0,enable=1,otherSubType=2};
//typedef std::shared_ptr<ctrl> Ptr;
ctrl(display* disp);
~ctrl(){};
void ctrllogic();
void ctrllogicTrans();
void ctrllogicHMI();
void checksubType();
int cmdType,cmdSubType;
private:
key* _mykey;
ServerEx* _myServerEx;
HMI* _myHmi;
};
#endif
#ifndef DISPLAY_HPP
#define DISPLAY_HPP
#include "head.hpp"
class display
{
public:
//typedef std::shared_ptr<display> Ptr;
display();
~display(){};
void run(display* disp);
ServerEx* _myServerEx;
ctrl* _myctrl;
HMI* _myHMI;
key* _mykey;
};
#endif
#ifndef HMI_HPP
#define HMI_HPP
#include "head.hpp"
class HMI
{
public:
//typedef std::shared_ptr<HMI> Ptr;
HMI(display* disp);
~HMI(){};
void DisplayFrame(ServerEx* serv);
void SetShowEn(bool cmd);
private:
bool _showEn;
};
#endif
#ifndef KEY_HPP
#define KEY_HPP
#include "head.hpp"
class key
{
public:
//typedef std::shared_ptr<key> Ptr;
key(display* disp);
~key(){};
int KeyDetect();
bool getJumpInfo();
bool getTransCmd();
private:
bool jump;
bool status;
};
#endif
#ifndef LOCK_HPP
#define LOCK_HPP
#include "head.hpp"
class mylock
{
public:
//typedef std::shared_ptr<lock> Ptr;
mylock(){};
~mylock(){};
void startLock();
void stopLock();
void startLockCmd();
void stopLockCmd();
void waitEvent();
void eventTrigger();
private:
};
#endif
#ifndef SERVER_HPP
#define SERVER_HPP
#include "head.hpp"
class recvhandler;
class recvState
{
public:
//typedef std::shared_ptr<recvState> Ptr;
virtual void revHead(){};
virtual void revCmd(){};
virtual void revData(){};
virtual void CurrentState(recvhandler *handler){};
std::vector<uchar> vec;
ServerEx *myServerEx;
static int Msglength;
static unsigned char Msgbuffer[1024];
protected:
const unsigned char RECHEAD_SIZE = 4;
const unsigned char RECCMD_SIZE = 6;
const unsigned char TYPE_INDEX = 0;
const unsigned char SUBTYPE_INDEX = 1;
const unsigned char LEN_INDEX = 2;
const unsigned int BUFFER_SIZE = 1024;
bool recv_OK;
};
class recvhandler
{
public:
recvhandler(recvState *state,ServerEx *myServ) : _recvState(state),_myServ(myServ) {}
~recvhandler() { delete _recvState; }
void SetState(recvState *state)
{
delete _recvState;
_recvState = state;
}
void GetState() { _recvState->CurrentState(this); }
ServerEx *_myServ;
private:
recvState *_recvState;
};
class revHeadState : public recvState
{
public:
revHeadState(ServerEx * serv);
~revHeadState(){};
void revHead(recvhandler *handler);
void CurrentState(recvhandler *handler);
ServerEx* myServerEx;
private:
};
class revCmdState : public recvState
{
public:
revCmdState(ServerEx * serv);
void revCmd(recvhandler *handler);
void CurrentState(recvhandler *handler);
};
class revDataState : public recvState
{
public:
revDataState(ServerEx * serv);
void revData(recvhandler *handler);
void CurrentState(recvhandler *handler);
};
class baseServer
{
public:
enum status
{
E_OK = 0,
E_NOK = -1
};
baseServer();
~baseServer(){};
int socketCreate(int type, int way, int ip, int port);
int socketBind(void);
int socketListen(int num);
int socketAccept(void);
virtual int socketDataHandler() = 0;
int socketDisconnect(void);
int socketCloseServer(void);
int getConnectfd(void);
private:
int serverfd, connectfd;
struct sockaddr_in serveraddr;
};
class mylock;
class ServerEx : public baseServer
{
public:
//typedef std::shared_ptr<ServerEx> Ptr;
ServerEx(display* disp);
~ServerEx(){};
void sendBeatCmd();
void sendTrans(bool cmd);
int socketDataHandler();
int ReceiveDataFrame();
int socketSendBeatFrame(uchar *cmdFrame);
int socketSendCmdFrame(uchar *cmdFrame);
void BeatDetect();
int getBeat();
void resetBeat();
recvState *_myRecv;
cv::Mat Img;
bool revOK;
private:
int sendCmd, sendSubCmd;
uchar cmdBuff[10];
mylock *_mylock;
int beat; /* keep alive signal with every 1s */
bool once;
};
#endif
效果圖

效果圖2.png