对应我上一篇文章Vscode mingw下opencv及多线程socket中待完成任务。
工程共享路径(在code/02文件夹中): https://github.com/AppleCai/Display
一,本周做了变更(版本变更为0.2)
1. 重新设计了交互协议。对于接收头及数据的解析使用了状态模式设计。
2. 添加了心跳检测功能:server每隔1s发给client,client检查若5s内没收到则断开连接。
3. 数据/控制/显示进行了分离设计,删除了之前使用线程挂起的方式来实现暂停方式。
4. 代码进行了重构,线程由原来的socket和key,还增加了HMI和控制线程。
5. 文件结构变更,拆分为如下6个模块
socket主要用来传输命令和数据。
控制模块主要控制是否正常传输数据,是否传输心跳数据命令,是否暂停显示。
key主要扫描s键(是否暂停传输),j键(是否暂停显示)
二,后续更新版本说明:
之前的2.1/2.2/2.3基本完成,后续需要完成
2.4 HMI图片显示添加ROI区域显示张数及叠加特质logo。(使用智能指针及模板类)
2.5 Server端切换到linux系统上。
2.6 重构HMI,分离为一个进程。
2.7 添加对图片的监视作用,添加弹窗报警及logDTC记录。(目的是使用进程间通信和共享内存)
2.8 添加守护进程。
2.9 进行性能测试,进行优化。
三,头文件:
#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 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 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 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 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 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 Ptr;
virtual void revHead(){};
virtual void revCmd(){};
virtual void revData(){};
virtual void CurrentState(recvhandler *handler){};
std::vector 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 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