【发布时间】:2018-04-09 04:22:50
【问题描述】:
我正在尝试使用 MQPUT 函数将带有 RFH2 标头的消息放入队列中。所述函数返回完成代码 2 和原因 2142,根据 IBM 文档,这意味着标头结构无效。此link 上的文档指定需要检查的字段。标头和消息描述符有以下内容:
MQMD:
StrucId = 'MD '
Version = 2
Report = 0
MsgType = 8
Expiry = -1
Feedback = 0
Encoding = 273
CodedCharSetId = 1208
Format = 'MQHRF2 '
Priority = -1
Persistence = 2
MsgId = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
CorrelId = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
BackoutCount = 0
ReplyToQ = ''
ReplyToQMgr = ''
UserIdentifier = ''
AccountingToken = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ApplIdentityData = ''
PutApplType = 0
PutApplName = ''
PutDate = ''
PutTime = ''
ApplOriginData = ''
GroupId = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
MsgSeqNumber = 1
Offset = 0
MsgFlags = 0
OriginalLength = -1
MQRFH2:
StrucId = 'RFH '
Version = 2
StrucLength = 128
Encoding = 273
CodedCharSetId = 0
Format = 'MQSTR '
Flags = 0
NameValueCCSID = 1208
我不明白标题为何无效以及如何解决此问题。 提前致谢。
int SendMessage(PMQHCONN connectionDescriptorPtr, PMQHOBJ queueDescriptorPtr, const char* payload, const char* message)
{
MQLONG completionResult;
MQLONG reason;
unsigned char* buffer = NULL;
PMQRFH2 pHeader;
PMQINT32 pNameValueLength;
PMQCHAR pNameValueData;
PMQCHAR pMessage;
PMQCHAR p;
MQLONG bufferLength;
MQLONG structLength;
MQLONG nameValueLength;
size_t payloadLength = strlen(payload);
size_t messageLength = strlen(message);
size_t sizeOfLength = sizeof(MQINT32);
size_t headerStructLength = MQRFH_STRUC_LENGTH_FIXED_2;
size_t padding = CalcPadding(payload);
size_t i;
/* mqmd */
MQMD md = {MQMD_DEFAULT};
MQPMO pmo = {MQPMO_DEFAULT};
structLength = (MQLONG) (headerStructLength + sizeOfLength + payloadLength + padding);
/* calc total buffer length */
bufferLength = (MQLONG) (headerStructLength + sizeOfLength + payloadLength + padding + messageLength);
printf("Lengths:\n"
" Header:\n"
" structure : %zu\n"
" length field : %zu\n"
" payload : length = %zu, padding = %zu (total: %zu)\n"
" Total : %d\n"
" Message : %zu\n"
"Total : %d\n",
headerStructLength,
sizeOfLength,
payloadLength, padding, payloadLength + padding,
structLength,
messageLength,
bufferLength
);
buffer = malloc((size_t) bufferLength);
/* setting up payload */
nameValueLength = (MQLONG) payloadLength;
pNameValueData = (PMQCHAR) (buffer + MQRFH_STRUC_LENGTH_FIXED_2 + sizeOfLength);
memcpy(pNameValueData, payload, (size_t) nameValueLength);
p = pNameValueData + nameValueLength;
for (i = 0; i < padding; i++)
{
*p = ' ';
p++;
nameValueLength++;
}
/* setting up valueLength */
pNameValueLength = (PMQINT32) (buffer + MQRFH_STRUC_LENGTH_FIXED_2);
*pNameValueLength = nameValueLength;
/* setting up message */
pMessage = pNameValueData + nameValueLength;
memcpy(pMessage, message, messageLength);
/* setting up header */
pHeader = (PMQRFH2) buffer;
memcpy(pHeader, &DefaultHeader, MQRFH_STRUC_LENGTH_FIXED_2);
memcpy(pHeader->Format, MQFMT_STRING, MQ_FORMAT_LENGTH);
pHeader->CodedCharSetId = MQCCSI_INHERIT;
pHeader->NameValueCCSID = 1208;
pHeader->StrucLength = (MQLONG) (headerStructLength + sizeOfLength + nameValueLength); /* !!! */
/* seeting up for put */
memcpy(md.Format, MQFMT_RF_HEADER_2, MQ_FORMAT_LENGTH);
md.MsgType = MQMT_DATAGRAM;
md.Persistence = MQPER_PERSISTENT;
pmo.Options = pmo.Options | MQPMO_NEW_MSG_ID | MQPMO_NO_SYNCPOINT;
MQPUT(*connectionDescriptorPtr, *queueDescriptorPtr, &md, &pmo, bufferLength, buffer, &completionResult, &reason);
free(buffer);
printf("Message put in queue with code %d and reason %d\n", completionResult, reason);
return 0;
}
我使用上面的代码来设置要发送的缓冲区。 问题被缩小到以下几种情况:
1) 如果我没有在标头中设置 StrucLength 字段(带有 !!! 的行),则消息已成功放入队列并带有可以在消息浏览器中读取的正确格式和数据
2) 如果我在代码中设置正确计算的字段,则消息将放入队列中,但显示为没有 MQRFH2 标头数据的 MQSTR 消息类型
3) 如果我确实设置了计算错误的字段,那么我会得到 2142 原因代码,这显然是问题的根源。
现在所有这些都让我想到了一个问题: 如果我放置消息,我不应该手动填充 StrucLength 字段吗?
【问题讨论】:
-
MQMD 的格式是什么?
-
@JoshMc, MQFMT_RF_HEADER_2
-
您是否尝试过将 CodedCharSetId 也设置为 1208?
-
@JoshMc,是的,我做到了。同样的错误。
-
我添加了描述符的内容