Visual c++ MQPUT消息长度
我有一个从队列中获取消息的函数Visual c++ MQPUT消息长度,visual-c++,ibm-mq,Visual C++,Ibm Mq,我有一个从队列中获取消息的函数 int MQGet(MQHOBJ Hobj,char* buffer,int* count, long waitInterval, MQLONG codePage) { MQLONG msgLen = 0; MQLONG msgSize = *count-1; MQGMO gmo = {MQGMO_DEFAULT}; MQMD md = {MQMD_DEFAULT}; /* Message Descriptor
int MQGet(MQHOBJ Hobj,char* buffer,int* count, long waitInterval, MQLONG codePage)
{
MQLONG msgLen = 0;
MQLONG msgSize = *count-1;
MQGMO gmo = {MQGMO_DEFAULT};
MQMD md = {MQMD_DEFAULT}; /* Message Descriptor */
gmo.Options = MQGMO_WAIT
| MQGMO_SYNCPOINT
| MQGMO_ACCEPT_TRUNCATED_MSG
| MQGMO_FAIL_IF_QUIESCING
| MQGMO_CONVERT ;
gmo.MatchOptions = MQMO_NONE;
//md.Format = ???
//md.CodedCharSetId = 850;
md.Encoding = MQENC_NATIVE;
if( codePage != 0 )
md.CodedCharSetId = codePage;
gmo.WaitInterval = waitInterval;
MQGET(Hcon, /* connection handle */
Hobj, /* object handle */
&md, /* message descriptor */
&gmo, /* default options (datagram) */
msgSize, /* message length */
buffer, /* message buffer */
&msgLen,
&CompCode, /* completion code */
&Reason); /* reason code */
*count = msgLen;
/* if (CompCode == MQCC_FAILED) {
return (int) Reason;
}*/
return (int) Reason;
}
int MQPut(char* queueName,char* buffer,int count, bool persist, MQLONG codePage)
{
MQOD od = {MQOD_DEFAULT};
strncpy(od.ObjectName, queueName, (size_t)MQ_Q_NAME_LENGTH);
memcpy(md.Format,MQFMT_STRING, (size_t)MQ_FORMAT_LENGTH); /* character string format */
memcpy(md.MsgId, /* reset MsgId to get a new one */
MQMI_NONE, sizeof(md.MsgId) );
memcpy(md.CorrelId, /* reset CorrelId to get a new one */
MQCI_NONE, sizeof(md.CorrelId) );
// memcpy(md.Encoding, /* para forzar convert en destino */
// MQENC_NATIVE, sizeof(md.Encoding) );
md.Encoding = MQENC_NATIVE;
if( persist )
md.Persistence = MQPER_PERSISTENT;
if( codePage != 0 )
md.CodedCharSetId = codePage;
// memcpy(md.CodedCharSetId, /* se agrega codificacion de caracteres a los mensajes */
// codePage, sizeof(md.CodedCharSetId) );
// MQPUT(Hcon, /* connection handle */
// Hobj, /* object handle */
// &md, /* message descriptor */
// &pmo, /* default options (datagram) */
// count, /* message length */
// buffer, /* message buffer */
// &CompCode, /* completion code */
// &Reason); /* reason code */
MQPUT1(Hcon, /* connection handle */
&od,
&md, /* message descriptor */
&pmo, /* default options (datagram) */
count, /* message length */
buffer, /* message buffer */
&CompCode, /* completion code */
&Reason); /* reason code */
if (CompCode == MQCC_FAILED) {
return (int) Reason;
}
return 0;
}
打开此按钮可将消息放入队列
int MQGet(MQHOBJ Hobj,char* buffer,int* count, long waitInterval, MQLONG codePage)
{
MQLONG msgLen = 0;
MQLONG msgSize = *count-1;
MQGMO gmo = {MQGMO_DEFAULT};
MQMD md = {MQMD_DEFAULT}; /* Message Descriptor */
gmo.Options = MQGMO_WAIT
| MQGMO_SYNCPOINT
| MQGMO_ACCEPT_TRUNCATED_MSG
| MQGMO_FAIL_IF_QUIESCING
| MQGMO_CONVERT ;
gmo.MatchOptions = MQMO_NONE;
//md.Format = ???
//md.CodedCharSetId = 850;
md.Encoding = MQENC_NATIVE;
if( codePage != 0 )
md.CodedCharSetId = codePage;
gmo.WaitInterval = waitInterval;
MQGET(Hcon, /* connection handle */
Hobj, /* object handle */
&md, /* message descriptor */
&gmo, /* default options (datagram) */
msgSize, /* message length */
buffer, /* message buffer */
&msgLen,
&CompCode, /* completion code */
&Reason); /* reason code */
*count = msgLen;
/* if (CompCode == MQCC_FAILED) {
return (int) Reason;
}*/
return (int) Reason;
}
int MQPut(char* queueName,char* buffer,int count, bool persist, MQLONG codePage)
{
MQOD od = {MQOD_DEFAULT};
strncpy(od.ObjectName, queueName, (size_t)MQ_Q_NAME_LENGTH);
memcpy(md.Format,MQFMT_STRING, (size_t)MQ_FORMAT_LENGTH); /* character string format */
memcpy(md.MsgId, /* reset MsgId to get a new one */
MQMI_NONE, sizeof(md.MsgId) );
memcpy(md.CorrelId, /* reset CorrelId to get a new one */
MQCI_NONE, sizeof(md.CorrelId) );
// memcpy(md.Encoding, /* para forzar convert en destino */
// MQENC_NATIVE, sizeof(md.Encoding) );
md.Encoding = MQENC_NATIVE;
if( persist )
md.Persistence = MQPER_PERSISTENT;
if( codePage != 0 )
md.CodedCharSetId = codePage;
// memcpy(md.CodedCharSetId, /* se agrega codificacion de caracteres a los mensajes */
// codePage, sizeof(md.CodedCharSetId) );
// MQPUT(Hcon, /* connection handle */
// Hobj, /* object handle */
// &md, /* message descriptor */
// &pmo, /* default options (datagram) */
// count, /* message length */
// buffer, /* message buffer */
// &CompCode, /* completion code */
// &Reason); /* reason code */
MQPUT1(Hcon, /* connection handle */
&od,
&md, /* message descriptor */
&pmo, /* default options (datagram) */
count, /* message length */
buffer, /* message buffer */
&CompCode, /* completion code */
&Reason); /* reason code */
if (CompCode == MQCC_FAILED) {
return (int) Reason;
}
return 0;
}
我现在的问题是我需要知道消息的确切长度
这是RunGet和RunPut服务
void CNTService::RunPut()
{
_finddata_t fdata;
char searchPath[MAX_PATH];
char fname[MAX_PATH];
char inputFileName[MAX_PATH];
char outputFileName[MAX_PATH];
char* t;
char* f;
intptr_t findHandle;
MQHOBJ Hobj;
DWORD status;
// long error;
// Set the service running flag
m_bIsRunning = true;
// Send a debug message that the service has started
DebugMsg("Entering CNTService::Run()");
// Create the search path for the find first routines
strcpy(searchPath,pathIn);
strcat(searchPath,"\\*.");
strcat(searchPath,inSuffix);
// Process the incomming files from the search path
while (m_bIsRunning) {
try {
// Connect to MQSeries
Hobj = 0;
if ((status = Connect(qMgrName,connName,channelName)) != 0) {
throw CError(MSG_MQSERIES_OPEN,itoa(status,conv1,10));
}
// Open the queue for writing
/* if ((Hobj = OpenQueue(queueName,error)) == 0) {
throw CError(MSG_MQSERIES_QUEUE,queueName,itoa(error,conv1,10));
}
*/
do {
// get a file to process
if ((findHandle = _findfirst(searchPath,&fdata)) != -1) {
do {
char* buffer = new char[fdata.size]; // Allocate memory space for the file contents
HANDLE ifile;
DWORD bread;
// Read the file to memory
sprintf(fname,"%s\\%s",pathIn,fdata.name);
// Open the file
//ifile = open(fname,O_RDONLY|O_BINARY);
ifile = CreateFile(fname,
FILE_READ_DATA,
0,
NULL,
OPEN_EXISTING,
0,
0);
if (ifile != INVALID_HANDLE_VALUE) {
// Read in it's contents to the memory buffered
if (ReadFile(ifile,buffer,fdata.size,&bread,0) == 0) {
DWORD err = GetLastError();
//l(ifile);
throw CError(MSG_OPEN_ERROR,fname,itoa(err,conv1,10));
}
// Close the file handle
CloseHandle(ifile);
// Check that the read byte coun is equal to the file size
if (bread != fdata.size) {
CloseHandle(ifile);
LogWarning(CError(MSG_FILE_SIZE,itoa(bread,conv1,10),itoa(fdata.size,conv2,10)));
continue;
}
}
else {
LogWarning(CError(MSG_OPEN_ERROR,fname,itoa(GetLastError(),conv1,10)));
continue;
}
// Put the message into the MQSeries queue
//TODO: Recalcular tamaño del buffer
if ((status = MQPut(queueName,buffer,bread, persist, codePage)) != 0) {
throw CError(MSG_MQSERIES_PUT,itoa(status,conv1,10));
}
// Create the output file name
f = fdata.name;
t = inputFileName;
while (*f && *f != '.')
*t++ = *f++;
*t++ = 0;
sprintf(outputFileName,"%s\\%s%08d.%s",pathOut,inputFileName,GetTickCount(),inSuffix);;
// Rename the file to the queue directory
if (rename(fname,outputFileName) == -1)
throw CError(MSG_RENAME,fname,outputFileName);
// Free used heap
delete[] buffer;
} while (_findnext(findHandle,&fdata) == 0);
// close the findfirst handle
_findclose(findHandle);
}
// Delay n milliseconds before processing the next request
Sleep(delay);
} while (m_bIsRunning);
}
// Trap thrown errors
catch (CError err) {
LogError(err);
}
// Trap unexpected errors
catch (...) {
LogError(CError(MSG_SERVICE,"Error no esperado.",itoa(GetLastError(),conv1,10)));
}
// Close the queue handle
// if (Hobj != 0)
// CloseQueue(Hobj);
// Disconnect from MQSeries
Disconnect();
// Delay for 5 seconds before reattempting to open MQSeries
Sleep(5000);
}
// Debug message
DebugMsg("Leaving CNTService::Run()");
}
// Get messages from MqSeries queue and store them in the output directory
void CNTService::RunGet()
{
char outputFileName[MAX_PATH];
MQHOBJ Hobj;
char tmpStr[512];
int count;
long error;
DWORD status;
static int sequence = 0;
// Initialize variables
m_bIsRunning = true;
// send a debug message theat the service is starting
DebugMsg("Entering CNTService::Run()");
// Set the localte to ascii
setlocale(LC_ALL,"C"); /* for C with ancii 1 byte characters */
// Process messages from the input queue
while (m_bIsRunning) {
try {
// Connect to MQSeries
Hobj = 0;
if ((status = Connect(qMgrName, connName, channelName)) != 0) {
throw CError(MSG_MQSERIES_OPEN,itoa(status,conv1,10));
}
// Open the input queue
if ((Hobj = OpenGetQueue(queueName, error)) == -1) {
throw CError(MSG_MQSERIES_QUEUE,queueName,itoa(error,conv1,10));
}
while (m_bIsRunning) {
// Get the message from the input queue
count = sizeof(buffer);
error = MQGet(Hobj, buffer, &count, waitInterval, codePage);
if (error == 0 || error == MQRC_TRUNCATED) {
int n;
int ofile;
// Log the file content to the system log
sprintf(tmpStr,"count=%d,reason=%d",count,error);
if (logAll)
LogInfo(CError(MSG_SERVICE,outputFileName,tmpStr,""));
// Write the message contents to a file
sprintf(outputFileName,"%s\\MSG%08d%03d.%s", pathQueue, GetTickCount(), sequence, outSuffix);
sequence = ++sequence % 1000;
ofile = open(outputFileName, O_WRONLY|O_BINARY|O_TRUNC|O_CREAT,S_IREAD|S_IWRITE);
if (ofile == -1) {
throw CError(MSG_OPEN_ERROR,outputFileName,itoa(GetLastError(),conv1,10));
}
n = write(ofile, buffer, count);
// Close the file
close(ofile);
// Check if the read in bytes differ
if (n != count){
throw CError(MSG_FILE_WRITE,itoa(n,conv1,10),itoa(count,conv2,10));
}else
MQCMIT();
}else {
if (m_bIsRunning) {
if (error != MQRC_NO_MSG_AVAILABLE) {
sprintf(tmpStr,"Error MQSeries reason=%d, error=",count,error);
throw CError(MSG_SERVICE,tmpStr,itoa(error,conv2,10));
}
Sleep(delay);
}
}
}
}
// Catch thrown errors
catch (CError err) {
LogError(err);
//revertimos mensaje a la cola
MQBACK();
}
// Catch unexpected errors
catch (...) {
LogError(CError(MSG_SERVICE,"Error no esperado."));
MQBACK();
}
// Close the queue handle
if (Hobj != 0)
CloseQueue(Hobj);
// Disconnect from mqseries
Disconnect();
// Delay until the next attemp
Sleep(delay);
}
// nothing more to do
DebugMsg("Leaving CNTService::Run()");
}
如果有人能帮忙,我会很感激的。
致意您已命名的
msgLen
调用中的输出参数将告诉您消息的实际长度。即使由于您提供的缓冲区不够大,消息在get上被截断,这也是正确的。因此,允许您使用更大的缓冲区重试MQGET
。在Morags answer的顶部。。“if(error==0 | | error==MQRC_TRUNCATED){”在我看来很不可靠-你不是说MQRC_TRUNCATED_MSG_被接受或MQRC_TRUNCATED_MSG_失败…请注意你正在进行数据转换(GMO_CONVERT),因此你需要注意缓冲区处理-这里有一个很好的问题描述(通常只有在处理dbcs字符时才有问题)…谢谢你的重新应用Morag,你是对的,但我现在面临的问题是,我必须根据消息内容的长度为MQPUT提供缓冲区,例如,我的msg看起来像这样{{1:xxxxxxxxxxxxxxxxx}{2:xxxxxxxxxxxxxxxxxxxxx}{4::27:1/1:40A:不可撤销的:20:++++:31C:+++:40E:XXXXXXXXXXXXXX:31D:XXXXXXXXXXXXXX:50:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX…-}因此,我需要读取该消息,并将其长度作为缓冲区长度传递给MQPUT,这就是我的问题所在,我不知道如何读取内容的长度。另一个评论是,我们需要从UNIX迁移到LINUX,所以在UNIX中我们没有问题,因为它接受任何缓冲区大小,但在LINUX中,您必须说明这一点o MQPUT是真正的长度。您正在放置的消息是您从MQGET检索到的消息,还是您只是自己执行MQPUT?您是否有可能编辑您的问题以仅包含问题所在。听起来与您上面的评论中的MQ无关。听起来像,“我有一个缓冲区,里面有一些内容,我不知道内容有多长”。另外,请您详细介绍一下UNIX和LINUX之间的区别。两者都需要MQPUT调用上消息的长度。