⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.h

📁 帮助VC的初学者了解向导生成程序的整体结构 Visual C++串口通信
💻 H
字号:
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#pragma pack(push,enter_protocol,4)
////////////////////////////////////
// CBlockingSocket

// needs winsock.h in the precompiled headers

#define SOCKET_BASE		(WM_USER+0x300)
#define SOCKET_UP		(SOCKET_BASE+0)
#define SOCKET_DOWN		(SOCKET_BASE+1)
#define FROM_SOCKET		(SOCKET_BASE+2)
#define SOCK_STATUSind	0x1113
#define SOCK_DATAind	0x1123

#define SOCK_STATE_ON	10
#define SOCK_STATE_OFF	0

#define RECEIVE		0x00
#define SEND		0x01
#define BOTH		0x02

typedef const struct sockaddr* LPCSOCKADDR;

class AFX_EXT_CLASS CBlockingSocketException : public CException
{
	DECLARE_DYNAMIC(CBlockingSocketException)
public:
// Constructor
	CBlockingSocketException(char* pchMessage);

public:
	~CBlockingSocketException() {}
	virtual BOOL GetErrorMessage(LPTSTR lpstrError, UINT nMaxError,
		PUINT pnHelpContext = NULL);
private:
	int m_nError;
	CString m_strMessage;
};

class AFX_EXT_CLASS CSockAddr : public sockaddr_in {
public:
	// constructors
	CSockAddr()
		{ sin_family = AF_INET;
		  sin_port = 0;
		  sin_addr.s_addr = 0; } // Default
	CSockAddr(const SOCKADDR& sa) { memcpy(this, &sa, sizeof(SOCKADDR)); }
	CSockAddr(const SOCKADDR_IN& sin) { memcpy(this, &sin, sizeof(SOCKADDR_IN)); }
	CSockAddr(const ULONG ulAddr, const USHORT ushPort = 0) // parms are host byte ordered
		{ sin_family = AF_INET;
		  sin_port = htons(ushPort);
	      sin_addr.s_addr = htonl(ulAddr); }
	CSockAddr(const char* pchIP, const USHORT ushPort = 0) // dotted IP addr string
		{ sin_family = AF_INET;
		  sin_port = htons(ushPort);
		  sin_addr.s_addr = inet_addr(pchIP); } // already network byte ordered
	// Return the address in dotted-decimal format
	CString DottedDecimal()
		{ return inet_ntoa(sin_addr); } // constructs a new CString object
	// Get port and address (even though they're public)
	USHORT Port() const
		{ return ntohs(sin_port); }
	ULONG IPAddr() const
		{ return ntohl(sin_addr.s_addr); }
	// operators added for efficiency
	const CSockAddr& operator=(const SOCKADDR& sa)
		{ memcpy(this, &sa, sizeof(SOCKADDR));
		  return *this; }
	const CSockAddr& operator=(const SOCKADDR_IN& sin)
		{ memcpy(this, &sin, sizeof(SOCKADDR_IN));
		  return *this; }
	operator SOCKADDR()
		{ return *((LPSOCKADDR) this); }
	operator LPSOCKADDR()
		{ return (LPSOCKADDR) this; }
	operator LPSOCKADDR_IN()
		{ return (LPSOCKADDR_IN) this; }
};

// member functions truly block and must not be used in UI threads
// use this class as an alternative to the MFC CSocket class
// 服务器:三步曲——Bind、Listen、Accept
// 客户端:Connect
class AFX_EXT_CLASS CBlockingSocket : public CObject
{
	DECLARE_DYNAMIC(CBlockingSocket)
public:
	SOCKET m_hSocket;
	CBlockingSocket() { m_hSocket = NULL; }
	void Cleanup();
	void Create(int nType = SOCK_STREAM);
	void Close();
	void Bind(LPCSOCKADDR psa);
	void Listen();
	void Connect(LPCSOCKADDR psa);
	BOOL Accept(CBlockingSocket& s, LPSOCKADDR psa);
	int Send(const char* pch, const int nSize, const int nSecs);
	int Write(const char* pch, const int nSize, const int nSecs);
	int Receive(char* pch, const int nSize, const int nSecs = 0);
	int SendDatagram(const char* pch, const int nSize, LPCSOCKADDR psa, 
		const int nSecs);
	int ReceiveDatagram(char* pch, const int nSize, LPSOCKADDR psa, 
		const int nSecs = 0);
	void GetPeerAddr(LPSOCKADDR psa);
	void GetSockAddr(LPSOCKADDR psa);
	static CSockAddr GetHostByName(const char* pchName, 
		const USHORT ushPort = 0);
	static const char* GetHostByAddr(LPCSOCKADDR psa);
	operator SOCKET()
		{ return m_hSocket; }
};

class AFX_EXT_CLASS CHttpBlockingSocket : public CBlockingSocket
{
public:
	DECLARE_DYNAMIC(CHttpBlockingSocket)
	enum {nSizeRecv = 1000}; // max receive buffer size (> hdr line length)
	CHttpBlockingSocket();
	~CHttpBlockingSocket();
	int ReadHttpHeaderLine(char* pch, const int nSize, const int nSecs);
	int ReadHttpResponse(char* pch, const int nSize, const int nSecs);
private:
	char* m_pReadBuf; // read buffer
	int m_nReadBuf; // number of bytes in the read buffer
};

////////////////////////////////////////////////////////////////////////////////
class AFX_EXT_CLASS CMyCriticalSec
{
private:
	CRITICAL_SECTION m_myCritical;

public:
	CMyCriticalSec();
	~CMyCriticalSec();
	void Enter();
	void Leave();
};
////////////////////////////////////

// 通用链表操作
struct list_head{
	struct list_head *next;
	struct list_head *prev;
};

#define INIT_LIST_HEAD(ptr)	do{ \
(ptr)->next=(ptr);(ptr)->prev=(ptr);}while(0)

#define list_entry(ptr,type,member) \
	((type*)((char*)(ptr)-(unsigned long)(&((type*)0)->member)))

class AFX_EXT_CLASS CMyList
{
private:
	struct list_head	m_myList;
	CMyCriticalSec		m_Critical;
	int					m_nCount;

public:
	CMyList();
	~CMyList();
	BOOL IsEmpty();
	void List_AddHead(struct list_head *New);
	void List_AddTail(struct list_head *New);
	void List_Del(struct list_head *entry);
	list_head* List_RemoveHead();
	list_head* List_RemoveTail();
	list_head* List_GetPrev(struct list_head *pCur);
	list_head* List_GetNext(struct list_head *pCur);
	list_head* List_GetHead();
	list_head* List_GetTail();
	void List_InsertAfter(struct list_head *pCur,struct list_head *pNew);
	void List_InsertBefore(struct list_head *pCur,struct list_head *pNew);
	int	 List_GetCount();
};

////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
#define	MSG_LEN			200   // 最大消息数目

// 通用数据块操作
#define MAX_BLOCK_LEN	2048   // 通用数据块长度

typedef struct{
	list_head list;
	UINT	message;
	int		nTotalLen;
	DWORD	dwSrcID;
	char	szTSDU[1];
}Ge_DataBlock;

#define BLK_HDRLEN		sizeof(Ge_DataBlock)

class AFX_EXT_CLASS CGeDataBlock
{
public:
	Ge_DataBlock*	m_pDataBlock;
	CMyList			m_BlockList;
	DWORD			m_dwBlockCount;
	DWORD			m_u32BlockLen;

public:
	CGeDataBlock(DWORD dwCount,DWORD u32BlkLen=MAX_BLOCK_LEN);
	~CGeDataBlock();
	//
	Ge_DataBlock* AllocBlock();
	void FreeBlock(Ge_DataBlock **ppBlock);
	BOOL IsValidBlock(Ge_DataBlock *pBlock);
	BOOL CopyToBlockData(Ge_DataBlock* pBlock,const char* pData,int nLen);
};

//////////////////////////////////////////////////////////////////////////////////
// 用于存放socket数据
typedef struct __SocketBuftag{
	char	szData[MAX_BLOCK_LEN];
	int		nLen;
	DWORD	dwSocketID;
}SOCKETBUF;
//

// 存放socket信息
typedef struct __SocketInfo{
	char	szLocalAddr[20];
	char	szRemoteAddr[20];
	WORD	wLocalPort;
	WORD	wRemotePort;
	DWORD	dwSendPacks;
	DWORD	dwSendBytes;
	DWORD	dwRecvPacks;
	DWORD	dwRecvBytes;
}SOCKETINFO;
//

// 一次存入n个数据,然后一个一个取出
class AFX_EXT_CLASS CAnalyseBuffer
{
private:
	char*	m_pszBuffer;
	int		m_nLeft;

public:
	CAnalysebuffer();
	void SetBuffer(char* pbuffer,int nLen);
	BOOL GetChar(char* pChar);
};

///////////////////////////////////////////////////////////////////////////////////

/*
协议层的抽象基类,继承类必须添加启动函数
*/
class AFX_EXT_CLASS CLayer
{
public:
	int		m_nState;
	DWORD	m_dwThreadID;
	HANDLE	m_hThread;
	CMyList	m_BlockList;

public:
	CLayer();
	void StartLayer();
	void EndLayer();
	virtual void Initialize();
	virtual void Run();
	virtual void Exit();

	~CLayer();
	BOOL PostMsg(Ge_DataBlock* pBlock);
	Ge_DataBlock* GetMsg();
// 线程主函数
	static UINT LayerThdFunc(LPVOID lParam);
};

///////////////////////////////////////////////////////////////////////////////////
/* 导出函数 */
///////////////////////////////////////////////////////////////////////////////////
extern "C" __declspec(dllimport) void BCDtoAscii(char *pAscii,char *pBCD,int nlen);
extern "C" __declspec(dllimport) int AsciitoBCD(char *pAscii,char *pBCD,int nlen);

///////////////////////////////////////////////////////////////////////////////////
/* 消息定义 */
///////////////////////////////////////////////////////////////////////////////////
#define	LAYER_BASE		(WM_USER+0x100)
#define	LAYER_MSG		(LAYER_BASE+0x01)

// 调试窗口
extern "C" __declspec(dllimport) void ConPrintf(char *fmt, ...);
extern "C" __declspec(dllimport) void PrintHead(char *fmt, ...);
extern "C" __declspec(dllimport) int testSubsystem(int level);
extern "C" __declspec(dllimport) void StartDebugPort();
extern "C" __declspec(dllimport) void StopDebugPort();

#ifndef NO_DEBUG_WIN
#define TRACE_SUBSYSF(level,subsys,msg){\
	if( testSubsystem(level) ){\
		PrintHead("\r\n%s, %s, @ %u",__FILE__,subsys,__LINE__);\
		ConPrintf msg ;\
	}\
}
#else
#define TRACE_SUBSYSF(level,subsys,msg)
#endif
//

// CRC与校验和计算
// 发送方计算CRC,并添加在数据域的末尾,len代表受保护数据域的长度
extern "C" __declspec(dllimport) void Addcrc16(unsigned char *buffer,int len);

// 接收方CRC校验,buffer为数据域长度首字节,len为数据域长度,包括发送方加入的CRC
extern "C" __declspec(dllimport) int Iscrc16OK(unsigned char *buffer,int len);

///////////////////////////////////////////////////////////////////////////////
/* 计算校验和 */
///////////////////////////////////////////////////////////////////////////////
extern "C" __declspec(dllimport) unsigned short CalcCheckSum(unsigned char *pbuffer,int len);
extern "C" __declspec(dllimport) BOOL IsCheckSumOK(unsigned char *pbuffer,int len,unsigned short toCheck);
//

#define TIMER_BASE		(WM_USER+0x110)
#define	MY_TIMER		(TIMER_BASE+0x01)
#define SET_TIMER		(TIMER_BASE+0x02)
#define STOP_TIMER		(TIMER_BASE+0x03)

#define MAX_TIMER_NUM	1000

// 实用函数
extern "C" __declspec(dllimport) void StartTimerThread();
extern "C" __declspec(dllimport) void EndTimerThread();

extern "C" __declspec(dllimport) BOOL GeStartTimer(int nTimerID,DWORD dwElapse,DWORD dwAcceptThdID,BOOL bIsLoop=FALSE);
extern "C" __declspec(dllimport) void GeStopTimer(int nTimerID);

///////////////////////////////////////////////////////////////////////
#pragma pack(pop,enter_protocol)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -