在WINCE下的点对点消息队列
2011-12-21 14:05
531 查看
在Wince下支持一种进程通信的方法,叫做点对点消息队列。为了和消息队列通信,一个或者一对进程创建一个读队列和一个写队列。调用创建函数或者打开队列的函数,只能指定它是读还是写,不能同时拥有读写权限。
当一个队列创建时,消息的最大个数和每条消息的最大长度被定义。如果队列已经填满,这时进行写操作,写函数将被阻塞(等待队列中出现空的槽),或者是立刻返回失败,或者是在返回失败之前等待一段指定的时间。同样的,读函数可以被阻塞,直到队列中出现新的未读消息,或者在返回失败前等待一段时间。
一条消息可以被标记为一条“警告”消息。警告消息被送往队列的最前,这样下一次读操作就能够读到这条警告消息,而不管队列中还有多少未读消息。同一时刻队列中只能传送一条警告消息。
说了这么多了,现在开始讲一下要用到的哪些API函数:
1、创建消息队列,调用这个函数:
HANDLE CreateMsgQueue(
LPCWSTR lpszName,//队列的名称
LPMSGQUEUEOPTIONS lpOptions //指向一个MSGQUEUEOPTIONS
);
LpOptions指向一个MSGQUEUEOPTIONS结构体指针,该结构体定义如下:
typedef MSGQUEUEOPTIONS_OS{
DWORD dwSize;//为sizeof(MSGQUEUEOPTIONS)
DWORD dwFlags;//描述队列的行为有MSGQUEUE_NOPRECOMMIT、//MSGQUEUE_ALLOW_BROKEN
DWORD dwMaxMessages;//同一时刻消息的最大数目
DWORD cbMaxMessage;// 每条消息最大长度
BOOL bReadAccess; // TRUE-创建读队列、FALSE – 创建写队列
} MSGQUEUEOPTIONS
如果一个已经创建的队列可以用下面函数来打开:
HANDLE OpenMsgQueue(
HANDLE hSrcProc,//原来打开队列的进程句柄
HANDLE hMsgQ,//CreagteMsgQueue返回来的句柄
LPMSGQUEUEOPTIONS lpOptions //指向一个MSGQUEUEOPTIONS
);
2、向队列写入一条消息,调用:
BOOL WriteMsgQueue(
HANDLE hMsgQ, // CreagteMsgQueue返回来的句柄
LPVOID lpBuffer,//指向包含消息的缓冲区
DWORD cbDataSize,//消息大小
DWORD dwTimeout,//指定等待时间
DWORD dwFlags //消息数据值
);
3、从队列读去消息,调用:
BOOL ReadMsgQueue(
HANDLE hMsgQ, // CreagteMsgQueue返回来的句柄
LPVOID lpBuffer, //指向接受消息的缓冲区
DWORD cbBufferSize, //缓冲区的大小
LPDWORD lpNumberOfBytesRead, //实际读取的消息大小
DWORD dwTimeout, //指定等待时间
DWORD* pdwFlags //存储消息数据值
);
了解上面的知识就可以写一个测试程序了,Process A 创建一个名为TEXT("MyQueueName")写入队列,Process A 向消息队列中写入消息。Process B 创建一个名为TEXT("MyQueueName")读队列,Process B 向消息队列中读取消息。程序如下:
Process A
view plaincopy to clipboardprint?
#define MSGQUEUENAME TEXT("MyQueueName")
#define MAX_MSGQUEUE_SIZE 10
#define MAX_MESSAGE_SIZE MAX_PATH +1
TCHAR szReadBuf[MAX_PATH] = {'a','b','c','d','e'};
HANDLE ghMsgQ = NULL;
DWORD WriteMsgQProc(LPVOID lpParameter);
MSGQUEUEOPTIONS opt1;
opt1.dwSize = sizeof(MSGQUEUEOPTIONS);
opt1.cbMaxMessage = MAX_MESSAGE_SIZE;
opt1.dwMaxMessages = MAX_MSGQUEUE_SIZE;
opt1.dwFlags = MSGQUEUE_ALLOW_BROKEN;
opt1.bReadAccess = FALSE;
ghMsgQ = CreateMsgQueue(pName,&opt1);
CreateThread(NULL,0,WriteMsgQProc,ghMsgQ,0,NULL);
DWORD WriteMsgQProc(LPVOID lpParameter)
{
HANDLE hMsgQ = reinterpret_cast<HANDLE>(lpParameter);
if(hMsgQ == NULL)
{
return 0;
}
while(TRUE)
{
if(WriteMsgQueue(hMsgQ,szReadBuf,MAX_PATH,INFINITE,0))
{
RETAILMSG(TRUE,(TEXT("Write Queue Value:%s\r\n"),szReadBuf));
}
Sleep(1000);
}
}
#define MSGQUEUENAME TEXT("MyQueueName")
#define MAX_MSGQUEUE_SIZE 10
#define MAX_MESSAGE_SIZE MAX_PATH +1
TCHAR szReadBuf[MAX_PATH] = {'a','b','c','d','e'};
HANDLE ghMsgQ = NULL;
DWORD WriteMsgQProc(LPVOID lpParameter);
MSGQUEUEOPTIONS opt1;
opt1.dwSize = sizeof(MSGQUEUEOPTIONS);
opt1.cbMaxMessage = MAX_MESSAGE_SIZE;
opt1.dwMaxMessages = MAX_MSGQUEUE_SIZE;
opt1.dwFlags = MSGQUEUE_ALLOW_BROKEN;
opt1.bReadAccess = FALSE;
ghMsgQ = CreateMsgQueue(pName,&opt1);
CreateThread(NULL,0,WriteMsgQProc,ghMsgQ,0,NULL);
DWORD WriteMsgQProc(LPVOID lpParameter)
{
HANDLE hMsgQ = reinterpret_cast<HANDLE>(lpParameter);
if(hMsgQ == NULL)
{
return 0;
}
while(TRUE)
{
if(WriteMsgQueue(hMsgQ,szReadBuf,MAX_PATH,INFINITE,0))
{
RETAILMSG(TRUE,(TEXT("Write Queue Value:%s\r\n"),szReadBuf));
}
Sleep(1000);
}
}
Process B
view plaincopy to clipboardprint?
#define MSGQUEUENAME TEXT("MyQueueName")
#define MAX_MSGQUEUE_SIZE 10
#define MAX_MESSAGE_SIZE MAX_PATH + 1
TCHAR szReadBuf[MAX_PATH] = {0};
HANDLE ghMsgQ = NULL;
DWORD ReadMsgQProc(LPVOID lpParameter);
MSGQUEUEOPTIONS opt1;
opt1.dwSize = sizeof(MSGQUEUEOPTIONS);
opt1.cbMaxMessage = MAX_MESSAGE_SIZE;
opt1.dwMaxMessages = MAX_MSGQUEUE_SIZE;
opt1.dwFlags = MSGQUEUE_ALLOW_BROKEN;
opt1.bReadAccess = TRUE;
ghMsgQ = CreateMsgQueue(pName,&opt1);
CreateThread(NULL,0,WriteMsgQProc,ghMsgQ,0,NULL);
DWORD ReadMsgQProc(LPVOID lpParameter)
{
HANDLE hMsgQ = reinterpret_cast<HANDLE>(lpParameter);
if(hMsgQ == NULL)
{
return 0;
}
while(TRUE)
{
DWORD dwRead;
DWORD dwFlag;
if(ReadMsgQueue(hMsgQ,szReadBuf,MAX_PATH,&dwRead,INFINITE,&dwFlag))
{
RETAILMSG(TRUE,(TEXT("Read Queue Value:%s\r\n"),szReadBuf));
}
Sleep(1000);
}
}
当一个队列创建时,消息的最大个数和每条消息的最大长度被定义。如果队列已经填满,这时进行写操作,写函数将被阻塞(等待队列中出现空的槽),或者是立刻返回失败,或者是在返回失败之前等待一段指定的时间。同样的,读函数可以被阻塞,直到队列中出现新的未读消息,或者在返回失败前等待一段时间。
一条消息可以被标记为一条“警告”消息。警告消息被送往队列的最前,这样下一次读操作就能够读到这条警告消息,而不管队列中还有多少未读消息。同一时刻队列中只能传送一条警告消息。
说了这么多了,现在开始讲一下要用到的哪些API函数:
1、创建消息队列,调用这个函数:
HANDLE CreateMsgQueue(
LPCWSTR lpszName,//队列的名称
LPMSGQUEUEOPTIONS lpOptions //指向一个MSGQUEUEOPTIONS
);
LpOptions指向一个MSGQUEUEOPTIONS结构体指针,该结构体定义如下:
typedef MSGQUEUEOPTIONS_OS{
DWORD dwSize;//为sizeof(MSGQUEUEOPTIONS)
DWORD dwFlags;//描述队列的行为有MSGQUEUE_NOPRECOMMIT、//MSGQUEUE_ALLOW_BROKEN
DWORD dwMaxMessages;//同一时刻消息的最大数目
DWORD cbMaxMessage;// 每条消息最大长度
BOOL bReadAccess; // TRUE-创建读队列、FALSE – 创建写队列
} MSGQUEUEOPTIONS
如果一个已经创建的队列可以用下面函数来打开:
HANDLE OpenMsgQueue(
HANDLE hSrcProc,//原来打开队列的进程句柄
HANDLE hMsgQ,//CreagteMsgQueue返回来的句柄
LPMSGQUEUEOPTIONS lpOptions //指向一个MSGQUEUEOPTIONS
);
2、向队列写入一条消息,调用:
BOOL WriteMsgQueue(
HANDLE hMsgQ, // CreagteMsgQueue返回来的句柄
LPVOID lpBuffer,//指向包含消息的缓冲区
DWORD cbDataSize,//消息大小
DWORD dwTimeout,//指定等待时间
DWORD dwFlags //消息数据值
);
3、从队列读去消息,调用:
BOOL ReadMsgQueue(
HANDLE hMsgQ, // CreagteMsgQueue返回来的句柄
LPVOID lpBuffer, //指向接受消息的缓冲区
DWORD cbBufferSize, //缓冲区的大小
LPDWORD lpNumberOfBytesRead, //实际读取的消息大小
DWORD dwTimeout, //指定等待时间
DWORD* pdwFlags //存储消息数据值
);
了解上面的知识就可以写一个测试程序了,Process A 创建一个名为TEXT("MyQueueName")写入队列,Process A 向消息队列中写入消息。Process B 创建一个名为TEXT("MyQueueName")读队列,Process B 向消息队列中读取消息。程序如下:
Process A
view plaincopy to clipboardprint?
#define MSGQUEUENAME TEXT("MyQueueName")
#define MAX_MSGQUEUE_SIZE 10
#define MAX_MESSAGE_SIZE MAX_PATH +1
TCHAR szReadBuf[MAX_PATH] = {'a','b','c','d','e'};
HANDLE ghMsgQ = NULL;
DWORD WriteMsgQProc(LPVOID lpParameter);
MSGQUEUEOPTIONS opt1;
opt1.dwSize = sizeof(MSGQUEUEOPTIONS);
opt1.cbMaxMessage = MAX_MESSAGE_SIZE;
opt1.dwMaxMessages = MAX_MSGQUEUE_SIZE;
opt1.dwFlags = MSGQUEUE_ALLOW_BROKEN;
opt1.bReadAccess = FALSE;
ghMsgQ = CreateMsgQueue(pName,&opt1);
CreateThread(NULL,0,WriteMsgQProc,ghMsgQ,0,NULL);
DWORD WriteMsgQProc(LPVOID lpParameter)
{
HANDLE hMsgQ = reinterpret_cast<HANDLE>(lpParameter);
if(hMsgQ == NULL)
{
return 0;
}
while(TRUE)
{
if(WriteMsgQueue(hMsgQ,szReadBuf,MAX_PATH,INFINITE,0))
{
RETAILMSG(TRUE,(TEXT("Write Queue Value:%s\r\n"),szReadBuf));
}
Sleep(1000);
}
}
#define MSGQUEUENAME TEXT("MyQueueName")
#define MAX_MSGQUEUE_SIZE 10
#define MAX_MESSAGE_SIZE MAX_PATH +1
TCHAR szReadBuf[MAX_PATH] = {'a','b','c','d','e'};
HANDLE ghMsgQ = NULL;
DWORD WriteMsgQProc(LPVOID lpParameter);
MSGQUEUEOPTIONS opt1;
opt1.dwSize = sizeof(MSGQUEUEOPTIONS);
opt1.cbMaxMessage = MAX_MESSAGE_SIZE;
opt1.dwMaxMessages = MAX_MSGQUEUE_SIZE;
opt1.dwFlags = MSGQUEUE_ALLOW_BROKEN;
opt1.bReadAccess = FALSE;
ghMsgQ = CreateMsgQueue(pName,&opt1);
CreateThread(NULL,0,WriteMsgQProc,ghMsgQ,0,NULL);
DWORD WriteMsgQProc(LPVOID lpParameter)
{
HANDLE hMsgQ = reinterpret_cast<HANDLE>(lpParameter);
if(hMsgQ == NULL)
{
return 0;
}
while(TRUE)
{
if(WriteMsgQueue(hMsgQ,szReadBuf,MAX_PATH,INFINITE,0))
{
RETAILMSG(TRUE,(TEXT("Write Queue Value:%s\r\n"),szReadBuf));
}
Sleep(1000);
}
}
Process B
view plaincopy to clipboardprint?
#define MSGQUEUENAME TEXT("MyQueueName")
#define MAX_MSGQUEUE_SIZE 10
#define MAX_MESSAGE_SIZE MAX_PATH + 1
TCHAR szReadBuf[MAX_PATH] = {0};
HANDLE ghMsgQ = NULL;
DWORD ReadMsgQProc(LPVOID lpParameter);
MSGQUEUEOPTIONS opt1;
opt1.dwSize = sizeof(MSGQUEUEOPTIONS);
opt1.cbMaxMessage = MAX_MESSAGE_SIZE;
opt1.dwMaxMessages = MAX_MSGQUEUE_SIZE;
opt1.dwFlags = MSGQUEUE_ALLOW_BROKEN;
opt1.bReadAccess = TRUE;
ghMsgQ = CreateMsgQueue(pName,&opt1);
CreateThread(NULL,0,WriteMsgQProc,ghMsgQ,0,NULL);
DWORD ReadMsgQProc(LPVOID lpParameter)
{
HANDLE hMsgQ = reinterpret_cast<HANDLE>(lpParameter);
if(hMsgQ == NULL)
{
return 0;
}
while(TRUE)
{
DWORD dwRead;
DWORD dwFlag;
if(ReadMsgQueue(hMsgQ,szReadBuf,MAX_PATH,&dwRead,INFINITE,&dwFlag))
{
RETAILMSG(TRUE,(TEXT("Read Queue Value:%s\r\n"),szReadBuf));
}
Sleep(1000);
}
}
相关文章推荐
- wince进程通信----点对点消息队列
- 在WINCE下的点对点消息队列
- 在WINCE下的点对点消息队列
- 点对点消息队列函数:用于WinCE的IPC机制
- 消息队列中点对点与发布订阅区别(good)
- 消息队列中点对点与发布订阅区别(good)
- spring整合activemq消息队列之点对点模式
- 消息队列-ActiveMQ学习笔记(二)-点对点消息实现
- 消息队列中点对点与发布订阅区别
- 最近发现系统rabbitmq丢消息比较严重,于是想了些方案来查找原因,给将消息发送方式添加确认机制。 我们在本地模拟了wms发送打标消息的场景. 1. 有事务 2. 先发点对点队列, 再发订
- 消息队列中点对点与发布订阅区别
- ActiveMQ:点对点队列消费者接收不到消息
- WINCE下消息队列的简单用法----MsgQueue
- WINCE下消息传递和消息队列
- Wince环境下实现收发消息队列
- 消息队列中点对点与发布订阅区别
- 消息队列中点对点与发布订阅区别(转)
- .NET Compact Framework 中的点对点消息队列
- WinCE下消息队列用法MsgQueue
- WinCE下消息队列用法