📄 protocol.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 + -