一个简单的MSMQ的发送和接收类

来源:互联网 发布:出国留学数据统计 编辑:程序博客网 时间:2024/06/05 22:50

1 发送类

#define MAX_FORMATNAME_LEN 2048class CMyMsmqSend{public:CMyMsmqSend(WCHAR* wszFormatName);~CMyMsmqSend();long sendData(WCHAR* szLable, const char* data, int dataSize,unsigned char priority);private:WCHAR _wszFormatName[MAX_FORMATNAME_LEN];bool _isOpened;QUEUEHANDLE _hQueue;};


CMyMsmqSend::CMyMsmqSend(WCHAR* wszFormatName){wcscpy(_wszFormatName,wszFormatName);_isOpened = false;_hQueue = NULL;}CMyMsmqSend::~CMyMsmqSend(){if (_isOpened){MQCloseQueue(_hQueue);}}long CMyMsmqSend::sendData(WCHAR* szLable, const char* data, int dataSize,unsigned char priority){HRESULT hr = MQ_OK;  if(!_isOpened){hr = MQOpenQueue(_wszFormatName,MQ_SEND_ACCESS,MQ_DENY_NONE,&_hQueue);if (FAILED(hr)){return hr;}_isOpened = true;}const int NUMBEROFPROPERTIES = 4;                   // Number of propertiesDWORD cPropId = 0;                                  // Property counterMQMSGPROPS msgProps;MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];HRESULT aMsgStatus[NUMBEROFPROPERTIES];aMsgPropId[cPropId] = PROPID_M_PRIORITY;                   // Property IDaMsgPropVar[cPropId].vt = VT_UI1;                      // Type indicatoraMsgPropVar[cPropId].bVal = priority;     // The message labelcPropId++;// Specify the message properties to be sent.aMsgPropId[cPropId] = PROPID_M_LABEL;                   // Property IDaMsgPropVar[cPropId].vt = VT_LPWSTR;                      // Type indicatoraMsgPropVar[cPropId].pwszVal = (LPWSTR)szLable;     // The message labelcPropId++;aMsgPropId[cPropId] = PROPID_M_BODY;                      // Property IDaMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;             // Type indicatorstring sBody;sBody.append(data,dataSize);aMsgPropVar[cPropId].caub.pElems = (LPBYTE)sBody.data();aMsgPropVar[cPropId].caub.cElems = dataSize;cPropId++;DWORD dwBodyType =  VT_VECTOR | VT_UI1; ;aMsgPropId[cPropId] = PROPID_M_BODY_TYPE;                  // Property IDaMsgPropVar[cPropId].vt = VT_UI4;                          // Type indicatoraMsgPropVar[cPropId].ulVal = dwBodyType;cPropId++;// Initialize the MQMSGPROPS structure.msgProps.cProp = cPropId;msgProps.aPropID = aMsgPropId;msgProps.aPropVar = aMsgPropVar;msgProps.aStatus = aMsgStatus;// Call MQSendMessage to send the message to the queue.hr = MQSendMessage(_hQueue,&msgProps,MQ_NO_TRANSACTION);return hr;}


2 同步接收类

class CMyMsmqRecvSyn{public:CMyMsmqRecvSyn(WCHAR* wszFormatName);~CMyMsmqRecvSyn();long recvData(WCHAR* szLable, unsigned char* data, int& dataSize);private:WCHAR _wszFormatName[MAX_FORMATNAME_LEN];bool _isOpened;QUEUEHANDLE _hQueue;};

CMyMsmqRecvSyn::CMyMsmqRecvSyn(WCHAR* wszFormatName){wcscpy(_wszFormatName,wszFormatName);_isOpened = false;_hQueue = NULL;}CMyMsmqRecvSyn::~CMyMsmqRecvSyn(){if (_isOpened){MQCloseQueue(_hQueue);}}long CMyMsmqRecvSyn::recvData(WCHAR* szLable, unsigned char* data, int& dataSize){HRESULT hr = MQ_OK;  if(!_isOpened){hr = MQOpenQueue(_wszFormatName,MQ_RECEIVE_ACCESS,MQ_DENY_NONE,&_hQueue);if (FAILED(hr)){return hr;}_isOpened = true;}const int NUMBEROFPROPERTIES = 5;DWORD cPropId = 0;                                 ULONG ulBufferSize = 2000;MQMSGPROPS msgprops;MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];HRESULT aMsgStatus[NUMBEROFPROPERTIES];aMsgPropId[cPropId] = PROPID_M_LABEL_LEN;           aMsgPropVar[cPropId].vt = VT_UI4;                   aMsgPropVar[cPropId].ulVal = MQ_MAX_MSG_LABEL_LEN; cPropId++;aMsgPropId[cPropId] = PROPID_M_LABEL;           aMsgPropVar[cPropId].vt = VT_LPWSTR;                   aMsgPropVar[cPropId].pwszVal = szLable; cPropId++;aMsgPropId[cPropId] = PROPID_M_BODY_SIZE;           aMsgPropVar[cPropId].vt = VT_NULL;                   cPropId++;aMsgPropId[cPropId] = PROPID_M_BODY_TYPE;           aMsgPropVar[cPropId].vt = VT_NULL;                   cPropId++;aMsgPropId[cPropId] = PROPID_M_BODY;           aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;    aMsgPropVar[cPropId].caub.pElems = data; aMsgPropVar[cPropId].caub.cElems = dataSize; cPropId++;msgprops.cProp = cPropId;                          msgprops.aPropID = aMsgPropId;                      msgprops.aPropVar = aMsgPropVar;                  msgprops.aStatus = aMsgStatus;   hr = MQReceiveMessage(_hQueue,                     // Queue handleINFINITE,                       // Max time to (msec) to receive the messageMQ_ACTION_RECEIVE,          // Receive action&msgprops,                  // Message property structureNULL,                       // No OVERLAPPED structureNULL,                       // No callback functionNULL,                       // No cursor handleMQ_NO_TRANSACTION           // Not in a transaction);dataSize = aMsgPropVar[2].ulVal;return hr;}



3 异步接收类

struct RECEIVE_CONTEXT{OVERLAPPED ov;                  // OVERLAPPED structureHANDLE hQueue;                  // Queue handleMQMSGPROPS *pmsgprops;          // Message properties structureWCHAR wszLable[MQ_MAX_MSG_LABEL_LEN];unsigned char* data;};typedef RECEIVE_CONTEXT RECEIVE_CONTEXT;typedef void (*mqDataProc)(WCHAR* wszLable, unsigned char* data, int iSize,void* param);class CMyMsmqRecv{public:CMyMsmqRecv(WCHAR* wszFormatName,int iThreadNum=2,int iRecvBufCount = 4,int iBufferSize=8192);~CMyMsmqRecv();long startRecv();void setDataProcFun(mqDataProc funProc,void* param);static unsigned int WINAPI CompletionPortThread(LPVOID lpParam);protected:unsigned int ThreadProc();private:WCHAR _wszFormatName[MAX_FORMATNAME_LEN];QUEUEHANDLE _hQueue;HANDLE _hPort;int _iThreadNum;int _iRecvBufCount;int _iBufferSize;RECEIVE_CONTEXT* _recvContext;vector<HANDLE> _vecThread;bool _bStop;mqDataProc _dataProc;void*_funParam;};

CMyMsmqRecv::CMyMsmqRecv(WCHAR* wszFormatName,int iThreadNum,int iRecvBufCount,int iBufferSize){wcscpy(_wszFormatName,wszFormatName);_hPort = NULL;_hQueue = NULL;_iThreadNum = iThreadNum;_iRecvBufCount = iRecvBufCount;_iBufferSize = iBufferSize;_dataProc = NULL;_funParam = NULL;}unsigned int CMyMsmqRecv::ThreadProc(){HANDLE hPort = (HANDLE)_hPort;DWORD dwNoOfBytes = 0;ULONG_PTR ulKey = 0;OVERLAPPED* pov = NULL;HRESULT hr = MQ_OK;for ( ; ; ){// Wait for a completion notification.pov = NULL;BOOL fSuccess = GetQueuedCompletionStatus(hPort,         // Completion port handle&dwNoOfBytes,  // Bytes transferred&ulKey,&pov,          // OVERLAPPED structure500       // Notification time-out interval);if(fSuccess == FALSE){if(GetLastError() == WAIT_TIMEOUT)continue;if(dwNoOfBytes == 0) return GetLastError() ;}if (pov == NULL){// An unrecoverable error occurred in the completion port. Wait for the next notification.continue;}// Get the base address of the RECEIVE_CONTEXT structure // containing the OVERLAPPED structure received.RECEIVE_CONTEXT* prc = CONTAINING_RECORD(pov, RECEIVE_CONTEXT, ov);// Get the final status (last error) for the message received.hr = MQGetOverlappedResult(&prc->ov);if (FAILED(hr)){return hr;}// Retrieve the application-specific data in the message.//long lAppSpecific = prc->pmsgprops->aPropVar[0].lVal;//wprintf(L"Message received. Thread ID: %x. Application-specific data: %ld\n",//GetCurrentThreadId(),//lAppSpecific//);if(_dataProc)_dataProc(prc->wszLable,prc->data,prc->pmsgprops->aPropVar[2].caub.cElems,_funParam);// Initiate the next message receive operation.hr = MQReceiveMessage(prc->hQueue,         // Queue handleINFINITE,            // Time to wait for a messageMQ_ACTION_RECEIVE,prc->pmsgprops,      // Pointer to an MQMSGPROPS structure&prc->ov,            // OVERLAPPED structure NULL,                // No callback functionNULL,                // No cursorMQ_NO_TRANSACTION    // Not in a transaction);if (FAILED(hr)){return hr;}}return hr;}unsigned int WINAPI CMyMsmqRecv::CompletionPortThread(LPVOID lpParam){CMyMsmqRecv* pThis = reinterpret_cast<CMyMsmqRecv*>(lpParam);return pThis->ThreadProc();}long CMyMsmqRecv::startRecv(){HRESULT hr = MQ_OK;hr = MQOpenQueue(_wszFormatName,MQ_RECEIVE_ACCESS,MQ_DENY_NONE,&_hQueue);if (FAILED(hr)){return hr;}// Create a new completion port._hPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,  // Do not associate a queue handle.NULL,                  // New port0,                     // No completion key0        // Number of concurrently executed threads);if (_hPort == NULL){MQCloseQueue(_hQueue);return GetLastError();}_hPort = CreateIoCompletionPort(_hQueue,           // Queue handle_hPort,            // Port handle0,                // No completion key0);if (_hPort == NULL){MQCloseQueue(_hQueue);return GetLastError();}// Create worker threads for the completion port.for(int cThread = 0; cThread < _iThreadNum; cThread++){unsigned int dwThreadId = 0;HANDLE hThread = NULL;hThread = (HANDLE)_beginthreadex(NULL,                  // Default thread security descriptor0,                     // Default stack sizeCompletionPortThread,  // Start routinethis,                 // Start routine parameter0,                     // Run immediately&dwThreadId            // Thread ID);if (hThread == NULL){MQCloseQueue(_hQueue);CloseHandle(_hPort);return GetLastError();}CloseHandle(hThread);}_recvContext = new RECEIVE_CONTEXT[_iRecvBufCount];for (int cReceive = 0; cReceive < _iRecvBufCount; cReceive++){_recvContext[cReceive].hQueue = _hQueue;_recvContext[cReceive].pmsgprops = new MQMSGPROPS;memset(_recvContext[cReceive].pmsgprops, 0, sizeof(MQMSGPROPS));memset(&_recvContext[cReceive].ov,0,sizeof(OVERLAPPED));const int NUMBEROFPROPERTIES = 5;_recvContext[cReceive].pmsgprops->aPropID = new MSGPROPID[NUMBEROFPROPERTIES];_recvContext[cReceive].pmsgprops->aPropVar = new MQPROPVARIANT[NUMBEROFPROPERTIES];_recvContext[cReceive].pmsgprops->aStatus = new HRESULT[NUMBEROFPROPERTIES];DWORD cPropId = 0;_recvContext[cReceive].pmsgprops->aPropID[cPropId] = PROPID_M_LABEL_LEN;_recvContext[cReceive].pmsgprops->aPropVar[cPropId].vt = VT_UI4;_recvContext[cReceive].pmsgprops->aPropVar[cPropId].ulVal = MQ_MAX_MSG_LABEL_LEN;cPropId++;_recvContext[cReceive].pmsgprops->aPropID[cPropId] = PROPID_M_LABEL;_recvContext[cReceive].pmsgprops->aPropVar[cPropId].vt = VT_LPWSTR;_recvContext[cReceive].pmsgprops->aPropVar[cPropId].pwszVal = _recvContext[cReceive].wszLable;cPropId++;_recvContext[cReceive].pmsgprops->aPropID[cPropId] = PROPID_M_BODY_SIZE;_recvContext[cReceive].pmsgprops->aPropVar[cPropId].vt = VT_NULL;cPropId++;_recvContext[cReceive].pmsgprops->aPropID[cPropId] = PROPID_M_BODY_TYPE;_recvContext[cReceive].pmsgprops->aPropVar[cPropId].vt = VT_NULL;cPropId++;_recvContext[cReceive].data = new unsigned char[_iBufferSize];_recvContext[cReceive].pmsgprops->aPropID[cPropId] = PROPID_M_BODY;_recvContext[cReceive].pmsgprops->aPropVar[cPropId].vt = VT_VECTOR | VT_UI1;_recvContext[cReceive].pmsgprops->aPropVar[cPropId].caub.pElems = _recvContext[cReceive].data;_recvContext[cReceive].pmsgprops->aPropVar[cPropId].caub.cElems = _iBufferSize;cPropId++;_recvContext[cReceive].pmsgprops->cProp = cPropId;hr = MQReceiveMessage(_hQueue,         // Queue handleINFINITE,            // Time to wait for a messageMQ_ACTION_RECEIVE,_recvContext[cReceive].pmsgprops,      // Pointer to an MQMSGPROPS structure&_recvContext[cReceive].ov,            // OVERLAPPED structure NULL,                // No callback functionNULL,                // No cursorMQ_NO_TRANSACTION    // Not in a transaction);if (FAILED(hr)){int i = GetLastError();return hr;}}return hr;}void CMyMsmqRecv::setDataProcFun(mqDataProc funProc,void* param){_dataProc = funProc;_funParam = param;}