FMQ API编程手册(C++语言)

FMQ API编程手册
(C++语言)


-- FMQ系列文档 --

目          录
第一章 FMQ API FOR C++ 概述2
1.1.FMQ API FOR C++ 编译器2
1.2.FMQ API FOR C++ 编程步骤2
第二章FMQ API FOR C++ 函数参考3
2.1.CONNECTFMQ(连接交换管理平台)3
2.2.DISCONNECTFMQ(断开与交换管理平台的连接)3
2.3.FMQGETLASTERROR(取得错误描述信息)4
2.4.FMQGETERRORTYPECODE(取得错误类型码)4
2.5.FMQGETERRORREASONCODE(取得错误原因代码)4
2.6.COMMIT(提交操作)5
2.7.ROLLBACK(回滚操作)5
2.8.DTCOMMIT(二次提交)5
2.9.SENDBUFFER(发送内存缓冲)6
2.10.SENDFILE(发送文件)8
2.11.GETFILE(收取文件)10
2.12.CREATEMESSAGE(建立消息)11
2.13.GETMESSAGEINTERFACE(取得消息)13
2.14.DESTORYMESSAGEINTERFACE (销毁消息接口)15
2.15.DELETEMESSAGE(删除消息)15
2.16.LOCKQUEUE(锁队列)16
2.17.UNLOCKQUEUE(解锁队列)16
2.18.GETQUEUECOUNT(取得队列数量)17
2.19.GETQUEUENAME(取得队列的名称)17
2.20.GETQUEUEDATATYPECOUNT(取得队列中数据类型的数量)17
2.21.GETQUEUEDATATYPENAME(取得数据类型的名称)18
2.22.GETQUEUEDEPTH(取得队列的深度)18
2.23.GETMESSAGELENGTH(取得消息长度)20
2.24.GETREMAINMESSAGELENGTH(取得剩余消息长度)20
2.25.GETDATAFROMMESSAGE(从消息中取得数据)20
2.26.WRITEDATAFROMMESSAGE(在消息中写入数据)20
2.27.SEEKMESSAGE(在消息中移动指针)21
第三章FMQ API FOR C++ 例子程序22
3.1.SENDTEST(文件发送)22
3.2.RCVTEST(接收文件)24
3.3.DELETETEST(删除消息)26
3.4.BROWSETEST(浏览队列)28
附录:FMQ 代码信息参考31
4.1.错误类型参考31
4.2.错误原因参考31

第一章 FMQ API FOR C++ 概述

1.1.FMQ API FOR C++ 编译器

FMQ API FOR C++ 支持VC60、VC7.0、VC7.1、G++ 等常用的C++编译器,通过加载动态库的方式可以支持任意C++编译器如Xlc、Borland C++等。

1.2.FMQ API FOR C++ 编程步骤

1.包含头文件#include “fmqapi.h”
2.调用函数ConnectFMQ 得到数据交换管理平台接口IFMQInterface
3.使用接口IFMQInterface 提供的方法进行操作,如发送文件、接收文件、提交操作、回滚操作等。当调用的方法返回失败的时候,可以调用FMQGetLastError函数查看错误信息、调用FMQGetErrorTypeCode函数查看错误类型、调用FMQGetErrorReasonCode函数查看错误原因代码。
4.最后调用DisConnectFMQ 关闭与数据交换管理平台之间的连接通道,并释放相关资源。








第二章FMQ API FOR C++ 函数参考

2.1.ConnectFMQ(连接交换管理平台)

函数说明:ConnectFMQ() 用来连接交换管理平台,在客户端与服务器之间建立连接通道,如果成功返回IFMQInterface接口,以后对平台的所有操作均通过IFMQInterface接口完成;如果失败函数返回NULL,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:const char* szQueueManagerName 队列管理器名称
                 unsigned short usListenerPort 队列服务监听端口
输出参数:函数本身输出IFMQInterface接口
备注信息:szQueueManagerName 输入NULL表示连接缺省队列管理器,usListenerPort输入0表示连接默认的监听端口
例子程序:
IFMQInterface* pFMQI = ConnectFMQ(szQMName);
if (!pFMQI)
{
printf("连接FMQ失败{错误描述%s}/n",FMQGetLastError());
printf("错误类型码[%d] 错误码[%d]/n",FMQGetErrorTypeCode(),FMQGetErrorReasonCode());
return -1;
}
else
{
printf(“连接FMQ成功/n”);
}
DisConnectFMQ(pFMQI);//断开连接、释放内存

2.2.DisConnectFMQ(断开与交换管理平台的连接)

函数说明:DisConnectFMQ() 用来断开与交换管理平台之间的连接,并释放所有申请的内存。
输入参数:pFMQInterface  IFMQInterface接口
输出参数:无
备注信息:无
例子程序:参考2.1的例子程序



2.3.FMQGetLastError(取得错误描述信息)

函数说明:FMQGetLastError() 用来取得错误的描述信息,当调用API中任意一个函数失败后,均可以通过这个函数取得错误的描述信息。
输入参数:无
输出参数:函数本身返回const char* 指向错误的描述信息
备注信息:无
例子程序:参考2.2.1的例子程序

2.4.FMQGetErrorTypeCode(取得错误类型码)

函数说明:FMQGetErrorTypeCode() 用来取得错误的类型码,当调用API中任意一个函数失败后,均可以通过这个函数取得错误的类型码,来确定下一步应用程序如何进行处理。
输入参数:无
输出参数:函数本身返回const long 为错误类型码
备注信息:错误类型码 0 表示没有错误
错误类型码10000表示函数调用的时候输入的参数出现错误
错误类型码20000表示服务器返回错误,需查看错误原因码
错误类型码40000表示磁盘IO方面出现错误
错误类型码80000表示与服务器连接方面出现错误
例子程序:参考2.1的例子程序

2.5.FMQGetErrorReasonCode(取得错误原因代码)

函数说明:FMQGetErrorReasonCode() 用来取得错误的原因代码,当调用API中任意一个函数失败后,均可以通过这个函数取得错误的原因代码。
输入参数:无
输出参数:函数本身返回const long 为错误原因代码
备注信息:请参考本文档中FMQ代码信息参考章节获得详细的信息
例子程序:参考2.1的例子程序


2.6.Commit(提交操作)

函数说明:Commit() 用来提交操作,当进行消息操作(取出、建立)时,需要要进行提交才能真正的生效。成功返回true,如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:无
输出参数:函数本身返回函数的执行结果
备注信息:支持无限级提交
例子程序:无

2.7.Rollback(回滚操作)

函数说明:Rollback() 用来回滚操作,当进行消息操作(取出、建立)时,为了保证事务的一致性可以通过回滚来撤销之前的所有操作。成功返回true,如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:无
输出参数:函数本身返回函数的执行结果
备注信息:支持无限级回滚,注意当客户端断开与服务器的连接时,所有未提交的操作会被自动回滚。
例子程序:无

2.8.DTCommit(二次提交)

函数说明:DTCommit() 用来提交操作,DTCommit与Commit的功能相同,当进行消息操作(取出、建立)时,需要要进行提交才能真正的生效。DTCommit支持二次提交操作,应用程序将提交的回调函数传入DTCommit,DTCommit在内部调用回调函数进行应用层的提交,并保证两个事务的一致性。成功返回true,如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:int(*)()
输出参数:函数本身返回函数的执行结果
备注信息:支持无限级提交
例子程序:无





2.9.SendBuffer(发送内存缓冲)

函数说明:SendBuffer() 通过IFMQInterface接口进行调用,作用是向交换管理平台发送一段缓冲,成功返回true,如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szTargetID目的地地址
usTargetIDCount目的地地址个数
szTargetQueueName目的地接收队列名称
szDataType数据类型
cPriority优先级别 0 ~ 9
cEncrypt加密算法 0 为没有加密 保留字段
cCompress   压缩算法 0 为没有压缩 保留字段
cSendType   发送类型 0 保留字段
cReply         是否回执 保留字段
ulTimeOut      超时时间 0 为此标记无效 单位秒
pBuffer               要发送的缓存
ulBufferLen    缓存的大小
szDataQueueName数据队列名称
输出参数:函数输出发送内存缓冲的结果
备注信息:每个目的地长度的最大值为10个字节,当有多个目的地地址的时候目的地地址之间用’/0’分割,数据类型最大长度为10个字节。
szTargetQueueName 目的地接收队列的名称,输入0或者””表示默认
cEncrypt、cCompress、cSendType、cReply为保留字段,在传输过程中全程保留输入的值,应用程序可以根据需要自行填写。
ulTimeOut 为超时时间单位是秒,输入0表示这个数据不会因为超时而被数据交换平台抛弃,存活时间的算法从建立消息开始计时,超过存活时间,消息会被交换平台删除,且这种删除是不可恢复的。
数据队列名称表示这段buffer发向哪一个队列,输入0表示默认的发送队列,输入其他队列的名称会被放置到相应的队列中,注意只有发送队列中的数据才能够别交换管理平台发送走。
例子程序:
IFMQInterface* pFMQI = ConnectFMQ(szQMName);
if (!pFMQI)
{
printf(“连接FMQ失败{错误描述%s}/n”,FMQGetLastError());
printf(“错误类型码[%d] 错误码[%d]/n”,FMQGetErrorTypeCode(),FMQGetErrorReasonCode());
return -1;
}
else
{
printf(“连接FMQ成功/n”);
}
if (!pFMQI-> SendBufferToPlat(“targetid”,//目的地
 1,//目的地地址个数
 “”,//目的地队列
 “datatype”,//数据类型
 5,//优先级别(0~9)
 0,0,0,0,//4个保留字段
                             0,//超时时间 0为永远不超时
                             “Hello World!”,//Buffer
                             Sizeof(“Hello World!”)+1,//BufferLen
                             0))//发送到默认队列中
{
printf(“发送Buffer失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
}
else
{
if (!pFMQI->Commit())//平台支持多级事务,如数据库类似发送一段buffer后需要调用Commit
{
printf(“提交操作失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
}
printf(“发送Buffer成功!/n”);
}
DisConnectFMQ(pFMQI);//断开连接、释放内存


2.10.SendFile(发送文件)

函数说明:SendFile() 通过IFMQInterface接口进行调用,作用是向交换管理平台发送一个文件,成功返回true,如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szTargetID目的地
usTargetIDCount目的地地址个数
szTargetQueueName目的地接收队列名称
szDataType数据类型
cPriority优先级别 0 ~ 9
cEncrypt加密算法 0 为没有加密 保留字段
cCompress   压缩算法 0 为没有压缩 保留字段
cSendType   发送类型 0 保留字段
cReply         是否回执 保留字段
ulTimeOut      超时时间 0 为此标记无效 单位秒
szFileDir               发送文件所在的目录
szFileName    发送文件的名称
szDataQueueName数据队列名称
输出参数:函数输出发文件的结果
备注信息:每个目的地长度的最大值为10个字节,当有多个目的地地址的时候目的地地址之间用’/0’分割,数据类型最大长度为10个字节。
szTargetQueueName 目的地接收队列的名称,输入0或者””表示默认
cEncrypt、cCompress、cSendType、cReply为保留字段,在传输过程中全程保留输入的值,应用程序可以根据需要自行填写。
ulTimeOut 为超时时间单位是秒,输入0表示这个数据不会因为超时而被数据交换平台抛弃,存活时间的算法从建立消息开始计时,超过存活时间,消息会被交换平台删除,且这种删除是不可恢复的。数据队列名称表示文件发向哪一个队列,输入0表示默认的发送队列,输入其他队列的名称会被放置到相应的队列中,注意只有发送队列中的数据才能够别交换管理平台发送走,发送文件名称的最大长度为75字节。

例子程序:
IFMQInterface* pFMQI = ConnectFMQ(szQMName);
if (!pFMQI)
{
printf(“连接FMQ失败{错误描述%s}/n”,FMQGetLastError());
printf(“错误类型码[%d] 错误码[%d]/n”,FMQGetErrorTypeCode(),FMQGetErrorReasonCode());
return -1;
}
else
{
printf(“连接FMQ成功/n”);
}
if (!pFMQI-> SendFileToPlat(“targetid”,//目的地
1,//目的地个数
“”,//目的地队列
“datatype”,//数据类型
5,//优先级别(0~9)
0,0,0,0,//4个保留字段
                            0,//超时时间 0为永远不超时
                            “d:/senddir”,//发送文件所在的目录
                            “hello word.txt”,//文件名称
                            0))//发送到默认队列中
{
printf(“发送文件失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
}
else
{
if (!pFMQI->Commit())//调用Commit提交操作
{
printf(“提交操作失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
}
printf(“发送文件成功!/n”);
}
DisConnectFMQ(pFMQI);//断开连接、释放内存


2.11.GetFile(收取文件)

函数说明:GetFile() 通过IFMQInterface接口进行调用,作用是从交换管理平台中收取一个文件,成功返回true,如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szDatatype数据类型
szFileDir文件所在的目录
szDataQueueName数据队列名称
bOverWrite如果有同名文件已经存在是否覆盖
输出参数:函数返回收取文件的结果
szFileName输出文件名称
pGWHead输出网关头信息
备注信息:如果接收的消息文件名称为空(发送的时候以消息方式发送),则系统会自动为这个消息生成一个文件名称。

例子程序:
IFMQInterface* pFMQI = ConnectFMQ(szQMName);
char szFileName[256];
if (!pFMQI-> GetFile(“xxxxx”,//! 数据类型
 “/rcvdir”,//! 文件所在的目录
 szFileName,//! 输出文件名 最长75字节
 0,//! 数据队列名称 (如果填写,数据将从本地数据队列中取出)
 0,//! 输出数据的网关头(输入NULL的时候,就不输出网关头)
 true)//! 重名是否覆盖
{
printf(“接收文件失败[%s]{%d,%d}/n”,
FMQGetLastError,FMQGetErrorTypeCode(),BHGetErrorReasongCode());
}
else
{
if (!pFMQI->Commit())//调用Commit提交操作
{
printf(“提交操作失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
}
printf(“接收文件[%s]成功!/n”, szFileName);
}
DisConnectFMQ(pFMQI);//断开连接、释放内存




2.12.CreateMessage(建立消息)

函数说明:CreateMessage()通过IFMQInterface接口进行调用,可以在交换管理平台中建立一个消息,这是一个低级函数,使用起来非常灵活,SendBuffer函数和SendFile函数也是通过本函数编写而成。如果函数调用成功,会返回所建消息的访问接口IFMQMessageInterface,通过该访问接口可以对消息进行读写操作;如果失败函数返回NULL,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szTargetID目的地
szTargetQueueName目的地接收队列名称
szDataType数据类型
cPriority优先级别 0 ~ 9
cEncrypt加密算法 0 为没有加密 保留字段
cCompress   压缩算法 0 为没有压缩 保留字段
cSendType   发送类型 0 保留字段
cReply         是否回执 保留字段
ulTimeOut      超时时间 0 为此标记无效 单位秒
ulMessageLength消息长度
szFileName文件名称
szDataQueueName数据队列名称
bClone是否要建立一个消息的克隆消息
pulMsgNO克隆消息的编号
pulMsgOffset克隆消息的偏移量
szDataQueueName数据队列名称
输出参数:函数本身返回消息访问接口IFMQMessageInterface,如果失败返回null
pulMsgNO返回消息的编号
pulMsgOffset返回消息的偏移量
备注信息:关于消息的克隆,克隆可以使多条消息共用同一个数据块,例如同一个消息需要发送给若干个目的地,可以让多个目的地共同使用同一个数据块,数据交换管理平台会分别为每一个消息块进行计数,这样做可以节省大量的IO操作,这个特性对于广播发送尤其有效。克隆的使用方法也很简单,在建立第一个消息的时候bClone = false ,并传入两个long 指针,如果函数调用成功,pulMsgNO, pulMsgOffset会返回所建消息的消息编号以及偏移量,以后再建立消息的时候,bClone = true,并传入pulMsgNO, pulMsgOffset即可。关于其他备注信息请参考SendBuffer 和 SendFile 中的说明。

例子程序:

IFMQInterface* pFMQI = ConnectFMQ(szQMName);
IFMQMessageInterface* pMessageInterface = pFMQI-> CreateMessage(
“targetid”,//目的地
1,//目的地个数
“”,//目的地队列
“datatype”,//数据类型
5,//优先级别(0~9)
0,0,0,0,//4个保留字段
                             0,//超时时间 0为永远不超时
12,//消息长度
“”//文件名称
);
if (!pMessageInterface)
{
printf(“建立消息失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
return 0;
}
if (!pMessageInterface-> WriteDataToMessage(“hello word !”,12))
{
printf(“写入消息失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
return 0;

}
//关闭消息接口
DestoryMessageInterface(pMessageInterface);
if (!pFMQI->Commit())//调用Commit提交操作
{
printf(“提交操作失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
return 0;
}
DisConnectFMQ(pFMQI);//断开连接、释放内存


2.13.GetMessageInterface(取得消息)
函数说明:GetMessageInterface()通过IFMQInterface接口进行调用,可以从交换平台中取得消息。这是一个低级函数,提供给用户一种更为灵活的方式取得消息,GetFile函数也是调用这个函数编写而成。如果函数调用成功,会返回所取消息的访问接口,通过该访问接口可以对消息进行读写操作;如果失败函数返回NULL,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szDatatype数据类型
szDataQueueName数据队列名称
bBrowseQueue是否遍历队列
pMsgHandle消息句柄(遍历的时候使用)
bDeleteFromQueue取出消息后是否删除

输出参数:函数本身返回执行的结果
pGWHead输出网关头信息
pMsgHandle输出消息句柄

备注信息:使用GetMessageInterface取得消息,返回消息操作接口,使用得当的话可以减少磁盘IO,尤其是带有数据头的消息。GetMessageInterface可以遍历整个队列,在一些特殊的应用中可以利用这个特性进行消息处理。遍历队列的方法为:首先找到第一条消息,输入bBrowseQueue =false bDeleteFromQueue= false第一条消息不是浏览消息且取出消息后不要删除这条消息,这时pMsgHandle会返回该消息的句柄,取下一条消息的时候,输入bBrowseQueue = true bDeleteFromQueue= false 以及第一条消息的返回的pMsgHandle,即可得到下一条消息了,如果下一条消息存在pMsgHandle变成了该消息的句柄,这样就可以循环调用本函数达到遍历整个队列的目的了。
例子程序:
IFMQInterface* pFMQI = ConnectFMQ(szQMName);
GWHead m_GWHead;
long lMsgHandle;
IFMQMessageInterface* pMessageInterface = pFMQI-> GetMessageInterface (
“szDataType”,//数据类型
“”,//队列名称
“datatype”,//数据类型
false,//是否遍历队列
&m_GWHead,//网关头
                             &lMsgHandle,//消息句柄
12,//消息长度
false//取出消息后是否删除
);
if (!pMessageInterface)
{
printf(“qude消息失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
return 0;
}
long lMsgLen = pMessageInterface-> GetMessageLength();
char pData = new char[lMsgLen];
if (lMsgLen != pMessageInterface-> GetDataFromMessage (pData, lMsgLen))
{
printf(“读取消息失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
return 0;

}
printf(“%s /n”, pData);
delete pData;
//关闭消息接口
DestoryMessageInterface(pMessageInterface);
//删除该消息
if (!pFMQI -> DeleteMessage(
“szDataType”,//数据类型
“”,//数据队列名称
&m_GWHead,//数据网关头
lMsgHandle,//消息句柄
))
{
printf(“删除消息失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
return 0;
}
DisConnectFMQ(pFMQI);//断开连接、释放内存


2.14.DestoryMessageInterface (销毁消息接口)

函数说明:DestoryMessageInterface()通过IFMQInterface接口进行调用,用来关闭CreateMessage() 或者GetMessageInterface()取得消息接口。
输入参数:pMessageInterface消息接口
输出参数:无
备注信息:无
例子程序:无

2.15.DeleteMessage(删除消息)

函数说明:DeleteMessage()通过IFMQInterface接口进行调用,用来删除一个消息,本函数与GetMessageInterface函数配合使用,删除以浏览方式取得的消息。GetMessageInterface得到该消息的GWHead与pMsgHandle,输入这两个参数和该消息的数据类型就可以删除该消息了。如果函数调用成功,会返回true;如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szDatatype数据类型
szDataQueueName数据队列名称
pGWHead输出网关头信息
lMsgHandle消息句柄
输出参数:函数本身返回执行的结果
备注信息:删除消息前一定要先关闭该消息的访问接口
例子程序:参考2.9的例子程序


2.16.LockQueue(锁队列)

函数说明:LockQueue()通过IFMQInterface接口进行调用,用来锁定队列,对于多线程、多进程同时操作队列时提供一个锁的机制。如果函数调用成功,会返回true;如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szDatatype数据类型
szDataQueueName数据队列名称
输出参数:函数本身返回执行的结果
备注信息:该锁是逻辑锁不是物理锁
例子程序:
IFMQInterface* pFMQI = ConnectFMQ(szQMName);
if (!pFMQI->LockQueue(“XXXXX”,//数据类型
“”//数据队列名称))
{
printf(“锁队列失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
return 0;
}

if (!pFMQI->UnlockQueue(“XXXXX”,//数据类型
“”//数据队列名称))
{
printf(“解锁队列失败[%s]{%d,%d}/n”,
FMQGetLastError(),FMQGetErrorTypeCode(),BHGetErrorReasongCode());
return 0;
}

DisConnectFMQ(pFMQI);//断开连接、释放内存

2.17.UnlockQueue(解锁队列)

函数说明:UnlockQueue()通过IFMQInterface接口进行调用,用来解锁队列,如果函数调用成功,会返回true;如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szDatatype数据类型
szDataQueueName数据队列名称
输出参数:函数本身返回执行的结果
备注信息:无
例子程序:参考2.15的例子程序

2.18.GetQueueCount(取得队列数量)

函数说明:GetQueueCount()通过IFMQInterface接口进行调用,用来取得队列管理器中管理的队列数量。如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:无
输出参数:函数本身返回队列的数量
备注信息:队列管理器中至少含有两个队列发送队列和接收队列,0为发送队列、1为接收队列
例子程序:请参考2.21

2.19.GetQueueName(取得队列的名称)

函数说明:GetQueueName()通过IFMQInterface接口进行调用,用来取得队列的名称。如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:lQueueNO队列的编号
输出参数:函数本身返回执行的结果
szQueueName数据队列名称
备注信息:发送队列 sendqueue 接收队列rcvqueue
例子程序:请参考2.21

2.20.GetQueueDataTypeCount(取得队列中数据类型的数量)

函数说明:GetQueueDataTypeCount()通过IFMQInterface接口进行调用,用来取得队列中数据类型的数量。如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szDataQueueName数据队列名称
输出参数:函数本身返回队列中含有的数据类型数量
备注信息:发送队列返回的是队列中的方向数
例子程序:请参考2.21







2.21.GetQueueDataTypeName(取得数据类型的名称)

函数说明:GetQueueDataTypeName()通过IFMQInterface接口进行调用,用来取得队列中某一数据类型的名称。如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:szDataQueueName数据队列名称
lDataTypeNO数据类型编号
输出参数:函数本身返回执行的结果
szDataTypeName 数据类型名称
备注信息:无
例子程序:请参考2.21


2.22.GetQueueDepth(取得队列的深度)

函数说明:GetQueueDepth()通过IFMQInterface接口进行调用,用来取得队列的深度,深度即队列中含有的消息数量
输入参数:szDatatype数据类型
szDataQueueName数据队列名称
ucPriority优先级别
输出参数:函数本身返回队列的深度
备注信息:优先级别输入’*’ (47)表示优先级全部
例子程序:

IFMQInterface* pFMQI = ConnectFMQ(szQMName);
long lQueueCount = pFMQI->GetQueueCount();
if (lQueueCount < 0)
{
printf("执行命令失败!{错误描述:[%s] 错误类型[%d] 错误码[%d]}/n",FMQGetLastError(),FMQGetErrorTypeCode(),FMQGetErrorReasonCode());
}
char szQueueName[256];
for (int i=0;i<lQueueCount;i++)
{
if (pFMQI->GetQueueName(i,szQueueName))
{
printf("队列[%s]/n",szQueueName);
//取数据类型数
long lDataTypeCount = pFMQI->GetQueueDataTypeCount(szQueueName);
if (lDataTypeCount < 0)
{
printf("执行命令失败!{错误描述:[%s] 错误类型[%d] 错误码[%d]}/n",FMQGetLastError(),FMQGetErrorTypeCode(),FMQGetErrorReasonCode());
break;
}
else
{
for (int m=0;m<lDataTypeCount;m++)
{
char szDataTypeName[256];
if (!pFMQI->GetQueueDataTypeName(szQueueName,m,szDataTypeName))
{
printf("执行命令失败!{错误描述:[%s] 错误类型[%d] 错误码[%d]}/n",FMQGetLastError(),FMQGetErrorTypeCode(),FMQGetErrorReasonCode());
break;
}
else
{
if (i == 0)
{
printf("    传输方向[%s]",szDataTypeName);
}
else
{
printf("    数据类型[%s]",szDataTypeName);
}
for (int n=strlen(szDataTypeName);n<18;n++)
{
printf(" ");
}
printf("深度[%d]/n",pFMQI->GetQueueDepth(szDataTypeName,szQueueName));
}
}
}
}
else
{
printf("执行命令失败!{错误描述:[%s] 错误类型[%d] 错误码[%d]}/n",FMQGetLastError(),FMQGetErrorTypeCode(),FMQGetErrorReasonCode());
break;
}
}

2.23.GetMessageLength(取得消息长度)

函数说明:GetMessageLength()通过IFMQMessageInterface接口进行调用,用来取得消息长度。
输入参数:无
输出参数:函数本身返回消息长度
备注信息:无
例子程序:无

2.24.GetRemainMessageLength(取得剩余消息长度)

函数说明:GetRemainMessageLength()通过IFMQMessageInterface接口进行调用,用来取得剩余的消息长度。
输入参数:无
备注信息:取消息、写入消息以及移动消息指针会对这个值产生影响
例子程序:无

2.25.GetDataFromMessage(从消息中取得数据)

函数说明:GetDataFromMessage()通过IFMQMessageInterface接口进行调用,用来从消息中取得数据。如果失败函数返回值与输入的ulDataLength不相等,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:pData数据缓冲
ulDataLength要取得的长度
输出参数:函数本身返回取得的字节数
备注信息:取得的数据的同时会向后移动消息指针
例子程序:无


2.26.WriteDataFromMessage(在消息中写入数据)

函数说明:WriteDataToMessage()通过IFMQMessageInterface接口进行调用,用来在消息中写入数据。如果失败函数返回false,可以调用FMQGetLastError查看错误信息、调用FMQGetErrorTypeCode查看错误类型、调用FMQGetErrorReasonCode查看错误原因代码。
输入参数:pData数据缓冲
ulDataLength要写入的长度
输出参数:函数本身返回执行结果
备注信息:写入数据的同时会向后移动消息指针
例子程序:无

2.27.SeekMessage(在消息中移动指针)

函数说明:SeekMessage()通过IFMQMessageInterface接口进行调用,用来在消息中移动指针,这个函数与C语言中的lseek函数类似
输入参数:ulOffset数据的相对位置
iSeekMode移动的模式
输出参数:函数本身返回执行结果
备注信息:iSeekMode SEEK_SET 从开始计算相对位置 SEEK_CUR 从当前位置计算相对位置 SEEK_END 从最后计算相对位置
例子程序:无


第三章FMQ API FOR C++ 例子程序

3.1.sendtest(文件发送)

sendtest 主要实现文件的发送,程序所在位置: FMQSamples/C++/sendtest

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "i_explatapi.h"
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
int main(int argc,char** argv)
{
if (argc != 9 )
{
printf("用法:%s 源发地 本地数据队列名称 目的地 数据类型 优先级(0~9) 路径 文件名 循环次数/n",argv[0]);
printf("如果要发送数据到目的地,本地数据队列名称填写为 sendqueue/n");
return -1;
}
IFMQInterface* pFMQI = ConnectFMQ(argv[1]);
if (!pFMQI)
{
printf("连接交换管理平台失败{%s}/n",FMQGetLastError());
return -1;
}
unsigned long ulCount = 0;
unsigned long ulShouldTime = (unsigned long) atol(argv[8]);
char* pDataQueueName;
if (!stricmp(argv[2],"sendqueue"))
{
pDataQueueName = NULL;
}
else
{
pDataQueueName = argv[2];
}
while(1)
{
if (!pFMQI->SendFile(argv[3],1,"",argv[4],atoi(argv[5]),0,0,0,0,0,argv[6],argv[7],pDataQueueName))
{
printf("发送文件失败{%s}/n",FMQGetLastError());
pFMQI->Rollback();
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
continue;
}
if (!pFMQI->Commit())
{
printf("提交失败{%s}/n",FMQGetLastError());
return -1;
}
++ulCount;
//if (ulCount%100 == 0)
{
printf("发送了 %d 个文件/n", ulCount);
}
//printf("Press Any Key ... /n");
//getch();
if (ulShouldTime)
{
if (ulCount >= ulShouldTime)
{
break;
}
}
}
DisConnectFMQ(pFMQI);
return 0;
}

3.2.rcvtest(接收文件)

rcvtest 主要实现文件的接收,程序所在位置: FMQSamples/C++/rcvtest

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "i_explatapi.h"
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif

int main(int argc,char** argv)
{
if (argc != 7 )
{
printf("用法:%s 队列管理器 数据队列名称 数据类型 路径 次数 没有数据是否退出/n",argv[0]);
printf("如果要从接收队列取数据,数据队列名称 填写为 rcvqueue/n");
return -1;
}
unsigned long ulCount = 0;
unsigned long ulShouldTime = (unsigned long) atol(argv[5]);
bool bQuitIfNoFileExists = atoi(argv[6])?true:false;
GWHead m_GWHead;
char szFileName[256];
bool bReturn;
IFMQInterface* pFMQI = ConnectFMQ(argv[1]);
if (!pFMQI)
{
printf("连接交换管理平台失败{%s}/n",FMQGetLastError());
return -1;
}
char* pDataQueueName = NULL;
if (stricmp(argv[2],"rcvqueue"))
{
pDataQueueName = argv[2];
}
while (1)
{
bReturn = pFMQI->GetFile(argv[3],argv[4],szFileName,pDataQueueName,&m_GWHead);
if (bReturn)
{
ulCount ++;
printf("接收文件[%s]->[%s]成功!总计个数[%d]/n",szFileName,argv[4],ulCount);
if (!pFMQI->Commit())
{
printf("提交失败");
}
if (ulShouldTime)
{
if (ulCount >= ulShouldTime)
{
break;
}
}
}
else
{
if (bQuitIfNoFileExists)
{
printf("没有数据类型为[%s]的消息/n",argv[3]);
DisConnectFMQ(pFMQI);
return 0;
}
//printf("没有文件,等待1秒/n");
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
}
DisConnectFMQ(pFMQI);
return 0;
}





3.3.deletetest(删除消息)

deletetest 主要实现删除消息,程序所在位置: FMQSamples/C++/deletetest

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "i_explatapi.h"
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
int main(int argc,char** argv)
{
if (argc != 6 )
{
printf("用法:%s 队列管理器 队列名称 数据类型 消息编号 数据标识/n",argv[0]);
return -1;
}
char szDataID[1024];
strcpy(szDataID,argv[5]);
GWHead m_GWHead;
memset(&m_GWHead,0,sizeof(GWHead));
long lMsgHandle = atol(argv[4]);
int istrlen = strlen(szDataID);
if (istrlen<16)
{
printf("删除消息失败,数据ID长度错误/n");
return -1;
}
char* p = szDataID + (istrlen-5);
m_GWHead.usNO = (unsigned short) atoi(p);
*p = 0;
p = szDataID + (istrlen - 15);
m_GWHead.lCreateTime = atol(p);
*p = 0;
strcpy(m_GWHead.SourceID,szDataID);

IFMQInterface* pFMQI = ConnectFMQ(argv[1]);
if (!pFMQI)
{
printf("连接交换管理平台失败{%s}/n",FMQGetLastError());
return -1;
}
if (!pFMQI->DeleteMessage(argv[3],argv[2],&m_GWHead,lMsgHandle))
{
printf("%s/n",FMQGetLastError());
}
else
{
printf("删除消息成功/n");
}
DisConnectFMQ(pFMQI);
return 0;
}


3.4.browsetest(浏览队列)

browsetest 主要实现浏览消息,程序所在位置: FMQSamples/C++/browsetest

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "i_explatapi.h"
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#define VT_COUNT 0
#define VT_DETAIL 1
#define VT_ALL 2
int main(int argc,char** argv)
{
if (argc != 6 )
{
printf("用法:%s 队列管理器 队列名称 数据类型 [COUNT|DETAIL|ALL] 返回的消息数(0表示全部)/n",argv[0]);
return -1;
}

int iViewType = VT_COUNT;
if (!stricmp(argv[4],"COUNT"))
{
iViewType = VT_COUNT;
}
else if (!stricmp(argv[4],"DETAIL"))
{
iViewType = VT_DETAIL;
}
else if (!stricmp(argv[4],"ALL"))
{
iViewType = VT_ALL;
}
else
{
printf("用法:%s 队列管理器 队列名称 数据类型 [COUNT|DETAIL|ALL] 返回的消息数(0表示全部)/n",argv[0]);
return 0;
}
unsigned long ulShouldCount = (unsigned long) atol(argv[5]);
IFMQInterface* pFMQI = ConnectFMQ(argv[1]);
if (!pFMQI)
{
printf("连接交换管理平台失败{%s}/n",FMQGetLastError());
return -1;
}

if (iViewType == VT_COUNT)
{
long lQueueDepth = pFMQI->GetQueueDepth(argv[3],argv[2]);
DisConnectFMQ(pFMQI);
if (lQueueDepth < 0)
{
printf(FMQGetLastError());
}
else
{
printf("队列管理器[%s]队列[%s]数据类型[%s]的深度为[%d]/n",argv[1],argv[2],argv[3],lQueueDepth);
}
return 0;
}
GWHead m_GWHead;
long lMsgHandle;
IFMQMessageInterface* pMessage = pFMQI->GetMessageInterface(argv[3],argv[2],false,&m_GWHead,&lMsgHandle,false);
unsigned long ulCount = 0;
while (pMessage)
{
if (iViewType == VT_DETAIL)
{
printf("消息编号[%d] 文件名称[%s] 数据标识[%s%010d%05d]/n",lMsgHandle,m_GWHead.FileName,m_GWHead.SourceID,m_GWHead.lCreateTime,m_GWHead.usNO);
}
else
{
printf("消息编号[%d] 文件名称[%s] 文件大小[%d] 源发地[%s] 目的地[%s]/n",lMsgHandle,m_GWHead.FileName,m_GWHead.ulMessageLength,m_GWHead.SourceID,m_GWHead.TargetID);
printf("优先级别[%d] 数据标识[%s%010d%05d]/n",m_GWHead.cPriority,m_GWHead.SourceID,m_GWHead.lCreateTime,m_GWHead.usNO);
}
pFMQI->DestoryMessageInterface(pMessage);
ulCount ++;
if (ulShouldCount)
{
if (ulCount >= ulShouldCount)
{
break;
}
}
pMessage = pFMQI->GetMessageInterface(argv[3],argv[2],true,&m_GWHead,&lMsgHandle,false);
}
printf("共计[%d]条消息/n",ulCount);
DisConnectFMQ(pFMQI);
return 0;
}


附录:FMQ 代码信息参考

4.1.错误类型参考

错误类型错误类型标识错误类型描述
0FMQERROR_NOERROR没有错误
10000FMQERROR_PARAMETERERROR参数输入错误
20000FMQERROR_SERVERERROR运行期错误
40000FMQERROR_IOERROR磁盘IO错误
80000FMQERROR_NETERROR网络层错误



4.2.错误原因参考

错误码错误类型错误描述
10001参数输入错误目的地不能为空
10002参数输入错误目的地长度范围错误
10003参数输入错误目的地队列名称长度
10004参数输入错误不能直接将消息发送到目的地的发送队列中
10005参数输入错误数据类型不能为空
10006参数输入错误数据类型长度范围错误
10007参数输入错误文件名称长度范围错误
10008参数输入错误数据队列名称长度范围错误
10009参数输入错误队列管理器名称长度范围错误
10010参数输入错误优先级别取值范围错误
10011参数输入错误以浏览的方式取得消息必须输入网关头
10012参数输入错误以浏览的方式取得消息必须输入消息句柄
10013参数输入错误以浏览的方式取得消息不能直接删除
10014参数输入错误要发送的文件不存在
10015参数输入错误接收目录不存在
10016参数输入错误GB2312字符集不存在(Java API 使用)
10017参数输入错误文件名称不能为空
10018参数输入错误要发送的缓存不能为空
20001运行期错误没有消息
20002运行期错误服务器返回信息错误
20003运行期错误文件已经存在
20004运行期错误远程代理服务器返回信息错误
40001磁盘IO错误打开文件失败
40002磁盘IO错误读取文件失败
40003磁盘IO错误写入文件失败
40004磁盘IO错误移动文件指针失败
40005磁盘IO错误关闭文件失败
40006磁盘IO错误队列文件的大小错误
80001网络层错误向服务器发送请求出错
80002网络层错误服务器响应超时
80003网络层错误等待服务器应答出错
80004网络层错误读取服务器发应答出错
80005网络层错误建立SOCKET失败
80006网络层错误连接服务器监听端口失败
80007网络层错误连接远程代理服务器监听端口失败
  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

xbjob

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值