3

我们正在使用 SMPP cloud-hopper 库将长消息发送到SMS 网关Innovativetxt.com,但似乎当我们将长消息拆分为每个部分 140 字节时。每条消息中的字符数达到 134 个字符。

然而,行业标准是 153 个字符应用于 GSM 编码长消息的每个部分。当我们通过 140 字节拆分时,我们只有 134 个字符是不是有问题?如果我们尝试提交大于 140 字节的消息,网关提供商会以消息体过大而拒绝它。

应将消息拆分为每个 153 个字符以提交给 SMSC,而不是通过每个 140 个字节发送消息。

拆分长消息的最佳方法是什么?按消息大小,即 140 字节或消息字符数?

任何人都通过 cloudhopper 或其他基于 Java 的库遇到了同样的问题,我们应该做什么。

4

2 回答 2

12

这是一个常见的混淆。你做的一切都是正确的。消息长度可以是 160 个字符(7 位 GSM 03.38)、140 个字符(8 位拉丁文)、70 个字符(16 位 UCS-2)。注意:160 * 7 == 140 * 8 == 70 * 16。

当您拆分长消息时,总部件号和部件索引等附加信息存储在消息正文中,即所谓的用户数据头 (UDH)。这个标题也发生了。因此,使用 UDH,您留下了 153 个 GSM 字符(7 位)、134 个字符/字节(8 位)有效负载或 67 个 2bytes-unicode 字符(16 位)

另请参阅http://www.nowsms.com/long-sms-text-messages-and-the-160-character-limit

对于您的情况,8 位 Contatenated 消息的 UDH 长度为 6 个字节。

UDH结构

0x05:UDH 的长度(后跟 5 个字节)
0x00:级联消息信息元素(8 位参考号)
0x03:信息元素数据的长度(后跟 3 个字节)
0xXX:此串联消息的参考编号
0xYY:连接消息中的片段数
0xZZ:连接消息中的片段编号/索引
总消息长度,位:160*7 = 140*8 = 1120
UDH 长度,位:6*8 = 48
左有效载荷,位:1120-48 = 1072
对于 GSM 03.38,您得到 1072/7 = 153 个 GSM(7 位)字符 + 1 个填充未使用的位。
对于拉丁语,您会得到 1072/8 = 134(8 位)字符。
对于 UCS-2,您将获得 1072/16 = 67(16 位)字符。

如您所见,153 个 GSM 字符等于 134 个字节减去 1 位。可能这 134 个字符是 Java 向您报告的。但是,一旦您拆分长文本消息,您最终会得到包含文本和 UDH 的二进制消息。您应该将消息视为二进制。我建议您从生成的部分进行二进制转储并进行调查。

于 2014-01-14T18:39:56.523 回答
2

您好 请参阅发送短短信或长短信的示例方法

    public synchronized String sendSMSMessage(String aMessage,
        String aSentFromNumber, String aSendToNumber,
        boolean requestDeliveryReceipt) {
    byte[] textBytes = CharsetUtil.encode(aMessage,
            CharsetUtil.CHARSET_ISO_8859_1);

    try {
        SubmitSm submitMsg = new SubmitSm();

        // add delivery receipt if enabled.
        if (requestDeliveryReceipt) {
            submitMsg
                    .setRegisteredDelivery(SmppConstants.REGISTERED_DELIVERY_SMSC_RECEIPT_REQUESTED);
        }
        submitMsg.setSourceAddress(new Address((byte) 0x03, (byte) 0x00,
                aSentFromNumber));
        submitMsg.setDestAddress(new Address((byte) 0x01, (byte) 0x01,
                aSendToNumber));
         if (textBytes != null && textBytes.length > 255) {
             submitMsg.addOptionalParameter(new Tlv(SmppConstants.TAG_MESSAGE_PAYLOAD, textBytes, "message_payload"));
         }else{
             submitMsg.setShortMessage(textBytes);
         }

        logger.debug("About to send message to " + aSendToNumber
                + ", Msg is :: " + aMessage + ", from :: "
                + aSentFromNumber);

        SubmitSmResp submitResp = smppSession.submit(submitMsg, 15000);

        logger.debug("Message sent to " + aSendToNumber
                + " with message id " + submitResp.getMessageId());
        return submitResp.getMessageId();
    } catch (Exception ex) {
        logger.error("Exception sending message [Msg, From, To] :: ["
                + aMessage + ", " + aSentFromNumber + ", " + aSendToNumber,
                ex);
    }

    logger.debug("Message **NOT** sent to " + aSendToNumber);
    return "Message Not Submitted to " + aSendToNumber;
}
于 2016-04-27T16:05:30.963 回答