【问题标题】:Invalid MQ header structure无效的 MQ 标头结构
【发布时间】: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,是的,我做到了。同样的错误。
  • 我添加了描述符的内容

标签: c ibm-mq


【解决方案1】:

对您的问题的简短回答是,如果您以上述方式创建 RFH2 标头,则需要设置长度。 RFH2 标头的长度可以不同。默认长度为 MQRFH_STRUC_LENGTH_FIXED_2。

关于为什么它不能正确显示,我不太明白为什么会这样。

我会推荐一些 RFH2 代码示例供您查看。这些样本可以在您的安装目录中找到,例如:C:\Program Files\IBM\WebSphere MQ\Tools\c\Samples\pubsub\amqsgr2a.c。 pubsub 目录中的示例具有构建 RFH2 标头函数。在这些示例中,长度是明确设置的。在获取和初始化存储方面,他们采取的方法与您略有不同。

还有 MQSETMP api,我相信它可以用来修改 RFH2 标头。这个 api 还可以在 RFH2 标头中为您维护和设置长度。我还没有找到它的用法示例。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2018-07-16
    • 2017-03-27
    • 1970-01-01
    • 1970-01-01
    • 2018-06-23
    • 2015-07-25
    • 2021-02-24
    • 2021-01-20
    • 1970-01-01
    相关资源
    最近更新 更多