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網絡層錯誤連接配接遠端代理伺服器監聽端口失敗