Обзор
SMPP — это протокол телекоммуникационной отрасли, впервые опубликованный компанией Aldiscon/Logica в конце 1990-х годов и в настоящее время поддерживаемый форумом разработчиков SMPP. Он определяет, как два участника обмениваются дискретными единицами, называемыми PDU (Protocol Data Units), по одному TCP-соединению: приложение устанавливает соединение, отправляет сообщения, получает подтверждения, поддерживает связь и разрывает соединение. Поскольку он является бинарным и ориентированным на соединение, он обеспечивает стабильную обработку миллионов сообщений в день с гораздо меньшими накладными расходами, чем открытие HTTP-запроса для каждого сообщения. Прочитайте эту страницу от начала до конца, и вы поймете каждое поле в реальной сессии SMPP.
Что такое SMPP и где он находится?
В сессии SMPP всегда участвуют две роли. ЭСМЕ (Внешняя Субъект коротких сообщений) — это ваше приложение — платформа для массовой рассылки SMS, сервис одноразовых паролей (OTP), система оповещений. SMSC Центр обработки коротких сообщений (Short Message Service Centre), называемый МС В версии 5.0 (Центр сообщений) — это операторский или агрегаторный узел, который хранит и пересылает сообщения между мобильными телефонами по мобильной сети. ESME подключается к SMSC; SMSC подключается к более широкой сети SS7 / мобильному ядру.
СМПП является основой A2P (От приложения к пользователю) обмен сообщениями — коды подтверждения, квитанции, оповещения, маркетинг — в отличие от P2P (Передача текстовых сообщений между двумя устройствами). A2P-трафик — это большой объем данных, генерируемый машиной и основанный на получении подтверждения доставки, именно для такой передачи и был разработан протокол SMPP.
Почему используется бинарный протокол TCP вместо HTTP? Одно соединение SMPP — это долгоживущий сокет. После его открытия вы избегаете рукопожатия TCP и TLS для каждого сообщения, можете одновременно передавать множество сообщений (асинхронное оконное соединение), а SMSC отправляет подтверждения доставки и входящие сообщения обратно по тому же соединению. При стабильно высокой пропускной способности это значительно эффективнее, чем HTTP API типа запрос/ответ — именно поэтому операторы и крупные отправители стандартизируют его.
История версий
- SMPP v3.3 — первая широко распространенная версия; в ней представлен основной набор PDU, но она предшествует TLV (дополнительным параметрам) и привязке приемопередатчика.
- SMPP v3.4 — доминирующая версия, используемая сегодня в производственной среде. Добавлены: привязка трансивера, необязательные параметры TLV, message_payload и data_sm. Практически любая реальная интеграция, которую вы будете создавать, использует версию 3.4.
- SMPP v5.0 — Новейшая версия. Переименовывает SMSC в MC, добавляет широковещательные PDU (broadcast_sm), сигнализацию состояния перегрузки и более стандартизированные TLV. Внедрение ограничено; сначала будет поддерживаться версия 3.4, а версия 5.0 будет рассматриваться как опциональная.
Архитектура и типы привязки
Топология проста: ESME открывает TCP-соединение с SMSC/MC и проходит аутентификацию. system_id и passwordНаправление, в котором сеансу разрешено передавать трафик, определяется во время привязки путем выбора одного из трех вариантов. режимы привязкиКаждый режим представляет собой отдельный блок данных привязки (PDU).
Только отправка. ESME может отправлять submit_sm, но не может получать deliver_sm в рамках этой сессии. Подтверждения должны поступать через отдельную привязку приемника.
Только прием. SMSC доставляет deliver_sm (входящие сообщения и DLR) в ESME, который не может отправлять сообщения в рамках этой сессии.
В обоих направлениях в рамках одной сессии — submit_sm на выходе, deliver_sm на входе. Введено в версии 3.4 и является рекомендуемым значением по умолчанию для новых интеграций.
Четвертый актер — маршрутизация: SMSC определяет для каждого сообщения, по какому маршруту или межсоединению нижестоящего оператора будет следовать отправленное сообщение к целевому мобильному устройству, и к какому привязанному ESME относится входящее (отправленное с мобильного устройства) сообщение.
В сети SMPP работает поверх TCP. Зарегистрированный в IANA порт по умолчанию — 2775 для простых соединений. СМППС — SMPP, обернутый в TLS — не имеет единого стандартного порта; провайдеры предоставляют к нему доступ через выбранный ими порт (на практике используются порты 3550, 8775 и 2776). Всегда используйте зашифрованный порт, назначенный вашим провайдером для производственной среды.
Жизненный цикл сессии
Каждая сессия SMPP проходит один и тот же путь: открытие TCP-соединения, привязка, поддержание соединения, обмен сообщениями и подтверждениями, затем отвязка и закрытие. На диаграмме ниже показана полная сессия приемопередатчика — каждая строка представляет собой один блок данных (PDU), синий цвет поступает от ESME к SMSC, зеленый — обратно.
Две важные детали. Во-первых, submit_sm_resp Возвращается немедленно и означает лишь «принято к доставке» — реальный результат станет известен позже из отчёта о доставке deliver_sm. Во-вторых, каждый запрос PDU соответствует _resp что перекликается с его sequence_numberТаким образом асинхронные ответы сопоставляются с запросами.
Анатомия PDU
Всё, что находится в соединении SMPP, является PDU. Каждый PDU начинается с фиксированного 16-байтового заголовка из четырёх 4-байтовых (32-битных, big-endian) целых чисел, за которым следует тело, зависящее от команды. Прочтите сначала заголовок — и вы точно будете знать, как читать остальное.
| Компенсировать | Поле | Размер | Значение |
|---|---|---|---|
| 0–3 | длина команды | 4 байта | Общая длина всего блока распределения питания (PDU) в октетах, включая заголовок и корпус. |
| 4–7 | command_id | 4 байта | Какая это операция (например, submit_sm = 0x00000004). Ответы устанавливают старший бит (0x80000000). |
| 8–11 | command_status | 4 байта | В запросах — 0; в ответах — код результата ESME_R* (0 = ESME_ROK = успех). |
| 12–15 | порядковый номер | 4 байта | Идентификатор, присвоенный вызывающим абонентом (1…0x7FFFFFFF); соответствующий _resp повторяет его для сопоставления. |
| 16… | тело | переменная | Обязательные параметры для этой команды, затем любые необязательные параметры TLV. |
Тело заканчивается любым количеством TLVs — необязательные параметры закодированы как Tag (2 байта), Length (2 байта), Value (байты длины). TLV — это способ расширения протокола в версии 3.4 без нарушения работы более старых версий: message_payload, receipted_message_id, поля конкатенации sar_* и многие другие все они передаются в виде TLV.
порядковый номер Это ключ к оконному управлению. Поскольку SMPP является асинхронным протоколом, ESME может отправить множество PDU submit_sm — каждый с увеличивающимся порядковым номером — прежде чем поступят какие-либо ответы. Когда PDU submit_sm_resp возвращаются, их порядковый номер указывает, на какую отправку отвечает каждый из них. Количество неподтвержденных PDU, разрешенных в процессе передачи, — это размер окна
Справочник по основным блокам распределения питания (PDU)
Это те операции, которые вы будете фактически использовать. Каждый запрос имеет PDU ответа, command_id которого — это идентификатор запроса с установленным старшим битом (0x80000000), поэтому submit_sm 0x00000004 соотносится с submit_sm_resp 0x80000004.
| ПДУ | command_id | Цель |
|---|---|---|
| bind_receiver | 0x00000001 | Откройте сессию только для приема. |
| bind_transmitter | 0x00000002 | Откройте сессию, предназначенную только для отправки. |
| bind_transceiver | 0x00000009 | Открыть двустороннюю сессию (v3.4). |
| submit_sm | 0x00000004 | Отправьте одно сообщение в один пункт назначения. |
| submit_multi | 0x00000021 | Отправьте одно сообщение максимум 254 адресатам. |
| deliver_sm | 0x00000005 | SMSC → ESME : подтверждение доставки или входящее (MO) сообщение. |
| data_sm | 0x00000103 | TLV-совместимая, двунаправленная альтернатива submit_sm / deliver_sm. |
| query_sm | 0x00000003 | Запросите у SMSC текущий статус отправленного сообщения. |
| cancel_sm | 0x00000008 | Отменить ранее отправленное, но еще не доставленное сообщение. |
| replace_sm | 0x00000007 | Заменить содержимое/расписание ожидающего сообщения. |
| enquire_link | 0x00000015 | Keepalive — подтверждение того, что сессия всё ещё активна. |
| unbind | 0x00000006 | Корректно завершите сессию SMPP. |
| generic_nack | 0x80000000 | Отрицательное подтверждение для не поддающегося анализу/недействительного PDU. |
submit_sm поле-по-полю
submit_sm Это PDU, который вы будете отправлять чаще всего. Его тело представляет собой последовательность обязательных параметров, а затем необязательных TLV. Именно эти поля имеют значение на практике.
| Поле | Что это делает |
|---|---|
| service_type | Необязательная категория приложения SMS (например, пустое поле или значение, используемое вашим SMSC для классов маршрутизации/биллинга). |
| source_addr_ton / _npi | Тип номера и индикатор плана нумерации отправителя. TON 5 = буквенно-цифровой (идентификатор отправителя); TON 1 = международный E.164. |
| source_addr | Адрес отправителя — короткий код, длинное число или буквенно-цифровой идентификатор отправителя (до 11 символов). |
| dest_addr_ton / _npi | TON / NPI для пункта назначения. Обычно TON 1 (международный), NPI 1 (ISDN / E.164). |
| destination_addr | Идентификатор получателя MSISDN обычно указывается в международном формате без знака «+» в начале. |
| esm_class | Битовая маска режима/типа сообщения — например, запрос подтверждения доставки обрабатывается параметром registered_delivery, а бит UDHI (0x40) указывает, что short_message начинается с UDH. |
| data_coding | DCS : 0 = GSM 7-бит (по умолчанию), 3 = Latin-1, 8 = UCS-2 (Unicode). Определяет ограничение на количество символов. |
| registered_delivery | Установите значение 1, чтобы запросить подтверждение доставки (deliver_sm) для этого сообщения; 0 — если подтверждение не запрашивается. |
| sm_length / short_message | Длина полезной нагрузки (0–254) и сами октеты сообщения, закодированные в соответствии с параметром data_coding. |
| message_payload (TLV 0x0424) | Необязательный TLV, содержащий тело сообщения вместо short_message — используется для длинного контента, превышающего 254 октета. |
| schedule_delivery_time / validity_period | Дополнительно можно указать абсолютное/относительное время для планирования доставки и продолжительность повторных попыток со стороны SMSC. |
Кодирование и конкатенация данных
data_coding Поле (схема кодирования данных, DCS) указывает телефону, как интерпретировать байты, и определяет, сколько символов помещается в одном SMS-сообщении.
| кодирование данных | Кодирование | Одинокий | Последовательный |
|---|---|---|---|
| 0 | 7-битный алфавит по умолчанию GSM | 160 символов | 153 символа / часть |
| 3 | Латинский 1 (ISO-8859-1), 8-битный | 140 символов | 134 символа / часть |
| 8 | UCS-2 (UTF-16BE) — Unicode | 70 символов | 67 символов / часть |
Сообщение, состоящее более чем из одного сегмента, разделяется и собирается заново на мобильном устройстве с помощью УДХ (Заголовок пользовательских данных) добавляется в начало каждой части. Элемент конкатенации использует IEI. 0x00 (8-битный ссылка) — 6-октетный заголовок, содержащий порядковый номер, общее количество компонентов и индекс данного компонента. Именно из-за этих 6 октетов ограничения на количество компонентов снижаются до 153 (GSM 7-бит) и 67 (UCS-2). При отправке UDH внутри short_message необходимо также установить бит UDHI (0x40) в esm_class.
Существует два способа отправки длинного контента: самостоятельно создавать сегментированные части UDH (каждая из которых представляет собой submit_sm с установленным UDHI) или передавать всё содержимое целиком в SMSC. message_payload TLV и позволяет сегментировать. Некоторые SMSC вместо этого принимают TLV sar_msg_ref_num / sar_total_segments / sar_segment_seqnum для описания конкатенации без UDH.
Накладные на доставку (DLR)
Когда вы устанавливаете registered_delivery = 1Впоследствии SMSC сообщает о судьбе сообщения, отправляя вам уведомление. deliver_sm с установленным битом подтверждения доставки в esm_class (0x04Текст отчёта о доставке хранится в поле short_message в виде общеизвестной строки ключевых слов:
id:1a2b3c4d5e sub:001 dlvrd:001 submit date:2607251432 done date:2607251432 stat:DELIVRD err:000 text:Your code is 8id соответствует message_id, полученному вами в ответе в submit_sm_resp (также отображается в TLV receipted_message_id 0x001E). stat Поле содержит конечное состояние:
| статистика | Значение |
|---|---|
| DELIVRD | Доставлено на телефон. Состояние успешного выполнения. |
| EXPIRED | Срок действия истек до момента доставки — SMSC прекратил повторные попытки. |
| DELETED | Сообщение было удалено в SMSC. |
| UNDELIV | Доставка не удалась — маршрут не указан, или же связаться с телефоном не удалось. |
| ACCEPTD | Принято (например, считано вручную на SMSC) — промежуточное состояние. |
| UNKNOWN | В SMSC отсутствует информация о состоянии сообщения. |
| REJECTD | Отклонено SMSC или нижестоящей сетью (например, заблокирован отправитель). |
Всегда отвечайте на сообщение deliver_m с помощью deliver_sm_respВ противном случае SMSC повторно отправит отчёт о доставке и может ограничить скорость или разорвать соединение. Обратите внимание, что форматирование отчётов о доставке не идеально стандартизировано — поставщики немного различаются по порядку полей и карте кодов ошибок.
Коды ошибок / состояния команд
Каждый блок распределения питания (PDU) имеет command_status в своем заголовке — ESME_R* Код. Ноль означает успех; всё остальное описывает причину отказа в запросе. Именно с такими кодами вы будете сталкиваться чаще всего.
| Код | Ценить | Значение |
|---|---|---|
| ESME_ROK | 0x00000000 | Нет ошибок — успех. |
| ESME_RINVMSGLEN | 0x00000001 | Недопустимая длина сообщения (проблема sm_length / полезной нагрузкой). |
| ESME_RINVCMDLEN | 0x00000002 | Недопустимое значение command_length — неправильная структура PDU. |
| ESME_RINVCMDID | 0x00000003 | Неизвестный или неподдерживаемый command_id. |
| ESME_RINVBNDSTS | 0x00000004 | Команда недействительна в текущем состоянии привязки (например, submit при привязке RX). |
| ESME_RALYBND | 0x00000005 | ESME уже заключила соглашение. |
| ESME_RINVSRCADR | 0x0000000A | Неверный адрес отправителя (идентификатор отправителя). |
| ESME_RINVDSTADR | 0x0000000B | Неверный адрес назначения. |
| ESME_RBINDFAIL | 0x0000000D | Сбой привязки — неверный system_id / пароль. |
| ESME_RINVPASWD | 0x0000000E | Неверный пароль. |
| ESME_RTHROTTLED | 0x00000058 | Ошибка регулирования скорости — вы превысили допустимую скорость передачи сообщений. |
| ESME_RSUBMITFAIL | 0x00000045 | submit_sm / submit_multi завершилась неудачей. |
| ESME_RSYSERR | 0x00000008 | Системная ошибка SMSC. |
Полный реестр, включая диапазоны цен конкретных поставщиков, доступен для поиска в [ссылка на реестр]. Справочник кодов ошибок SMPP
Пропускная способность, оконная обработка и регулирование.
Пропускная способность в SMPP измеряется в ТПС — транзакций (submit_sm) в секунду — и это регулируется двумя факторами: скоростью, которую разрешает SMSC, и количеством сообщений, которые вы поддерживаете в процессе передачи. Поскольку SMPP является асинхронным протоколом, вам не нужно ждать каждого submit_sm_resp перед отправкой следующего PDU. Количество неподтвержденных отправлений, которые вы разрешаете одновременно, зависит от вас. размер окна (обычно 10–100). Большее окно скрывает задержку передачи данных в обоих направлениях и повышает эффективную производительность в секунду — до максимального значения SMSC.
- Уважайте газ. Когда SMSC возвращает ESME_RTHROTTLED (0x58), сделайте паузу и повторите попытку с экспоненциальной задержкой, а не с постоянным нажатием кнопки привязки, что может привести к разрыву соединения.
- Поддерживайте связь в ритме. Отправляйте запрос enquire_link примерно каждые 30 секунд в режиме ожидания; если несколько запросов остаются без ответа, считайте, что ссылка не работает.
- Восстановите связь обдуманно. При разрыве соединения выполните повторное подключение и повторное привязывание с задержкой и дрожанием; не используйте замкнутый цикл. Отслеживайте незавершенные порядковые номера, чтобы вы могли согласовать отчёты о доставке после повторного подключения.
- Применяйте байонеты осторожно. Более высокий совокупный показатель TPS обычно достигается за счет множественных подключений — но только в пределах лимита, разрешенного вашим провайдером для каждой учетной записи.
Пример кода
Примерный поток подключения → привязки → отправки в псевдокоде в стиле Node. Настоящие библиотеки SMPP (например, node-smpp, jSMPP для Java или python-smpplib) обрабатывают кодирование PDU за вас; здесь показана структура сессии, а не API конкретной библиотеки.
import smpp from "smpp";
// 1. Open a TCP (or TLS) session to the SMSC.
const session = smpp.connect({
// Host, port and bind credentials come with your test access.
// Plain SMPP conventionally uses 2775; the TLS port is provided with your account.
url: process.env.SMPP_URL!, // e.g. smpp://<host>:2775 (plain) or smpps://<host>:<tls-port>
auto_enquire_link_period: 30000, // keepalive every 30s
});
// 2. Bind as a transceiver.
session.bind_transceiver(
{
system_id: "YOUR_SYSTEM_ID",
password: "YOUR_PASSWORD",
system_type: "",
},
(pdu) => {
if (pdu.command_status !== 0) {
throw new Error("bind failed: 0x" + pdu.command_status.toString(16));
}
// 3. Submit a Unicode message, asking for a delivery receipt.
session.submit_sm(
{
source_addr_ton: 5, // alphanumeric Sender ID
source_addr: "BroadNet",
dest_addr_ton: 1, // international E.164
destination_addr: "447700900123",
registered_delivery: 1, // request a DLR
data_coding: 8, // UCS-2 (Unicode)
short_message: "Your code is 8123",
},
(submitResp) => {
// submit_sm_resp returns the SMSC message_id.
console.log("accepted, message_id =", submitResp.message_id);
}
);
}
);
// 4. Receive delivery receipts on the same session.
session.on("deliver_sm", (pdu) => {
if ((pdu.esm_class & 0x04) === 0x04) { // delivery-receipt bit
console.log("DLR:", pdu.short_message.message);
}
session.send(pdu.response()); // ALWAYS deliver_sm_resp
});BroadNet SMPP
BroadNet использует шлюз SMSC операторского класса, который принимает привязки SMPP v3.4 через TLS. Вы получаете: привязки трансивера, высокую скорость передачи данных в секунду с асинхронным оконным управлением, полные подтверждения доставки, поддержку Unicode и конкатенацию, а также IP-адрес, включенный в список разрешенных, с использованием учетных данных для связи с операторами по всему миру. Это тот же протокол, который рассматривается на этой странице — и он ориентирован на реальные маршруты.
Запросите привязку для вашей учетной записи, и наша команда инженеров по продажам настроит ваш system_id, TLS-конечную точку, TPS и список разрешенных IP-адресов. Или ознакомьтесь с инструкцией по настройке шлюза.
Часто задаваемые вопросы
Какой порт использует SMPP?
В соответствии с требованиями IANA, по умолчанию используется TCP-порт 2775 для обычного SMPP. Единого стандартного порта TLS не существует — SMPPS (SMPP поверх TLS) обычно работает на порту, специфичном для провайдера, например, 3550, 8775 или 2776, поэтому всегда используйте порт, назначенный вашим оператором SMSC. BroadNet публикует информацию о хосте привязки, обычном порте и порте TLS вместе с вашими учетными данными.
В чём разница между submit_sm и data_sm?
submit_sm — это основной PDU, используемый ESME для отправки одного короткого сообщения; он содержит классическое поле short_message (до 254 октетов) плюс необязательные TLV. data_sm — это упрощенная симметричная альтернатива, представленная в SMPP v3.4, которая всегда содержит содержимое TLV message_payload и может передаваться в любом направлении (ESME→SMSC или SMSC→ESME). Большая часть A2P-трафика использует submit_sm; data_sm используется там, где предпочтительна его двунаправленная структура, состоящая только из TLV.
Как SMPP обрабатывает Unicode?
Передача символов Unicode осуществляется путем установки параметра data_coding в значение 8 (UCS-2 / UTF-16BE big-endian). Один сегмент UCS-2 содержит 70 символов; объединенные части UCS-2 содержат по 67 символов каждая, поскольку заголовок конкатенации UDH расходует 6 октетов. GSM 7-битный (data_coding 0) является значением по умолчанию для базового латинского текста размером 160/153 символа.
Что такое привязка приемопередатчика?
Привязка приемопередатчика (TRX) — это единая сессия SMPP, открытая с параметром bind_transceiver, которая может как отправлять сообщения (submit_sm), так и получать сообщения и подтверждения доставки (deliver_sm) по одному и тому же TCP-соединению. Она заменяет старый подход, при котором открывались отдельные привязки передатчика и приемника, и является рекомендуемым режимом для большинства современных интеграций.
Почему следует использовать SMPP вместо HTTP API?
SMPP — это постоянный бинарный протокол TCP, разработанный для обеспечения стабильно высокой пропускной способности. Длительное соединение позволяет избежать рукопожатий TLS/TCP для каждого сообщения, поддерживает асинхронное оконное взаимодействие (много незавершенных запросов submit_sm до получения подтверждения) и обеспечивает доставку в реальном времени как запросов deliver_sm, так и сообщений, отправленных с мобильных устройств, обратно через тот же сокет. Для очень больших и стабильных объемов A2P-запросов он эффективнее, чем HTTP-запрос/ответ; HTTP REST проще для меньших объемов и более насыщенных каналов.
Что такое enquire_link?
enquire_link — это легковесный PDU для подтверждения активности соединения, который отправляет одна из сторон для подтверждения того, что сессия SMPP и базовое TCP-соединение всё ещё активны; другая сторона отвечает сообщением enquire_link_resp. Обычно он отправляется каждые 30 секунд в периоды простоя. Если несколько сообщений enquire_link остаются без ответа, другая сторона считает соединение неактивным и переподключается.
Что означает параметр command_length в заголовке PDU?
Поле command_length — это первые 4 байта заголовка каждого PDU SMPP, содержащие общую длину всего PDU в октетах, включая сам 16-байтовый заголовок и всё тело. Приёмник сначала считывает эти 4 байта, чтобы точно определить, сколько ещё байтов нужно прочитать для полного PDU, прежде чем анализировать command_id, command_status и sequence_number.
Что такое отчёт о доставке (DLR) в системе SMPP?
Подтверждение доставки — это SMSC, сообщающее ESME окончательную судьбу отправленного сообщения. Оно поступает в виде PDU deliver_sm с установленным битом подтверждения доставки esm_class (0x04). short_message содержит строку подтверждения с ключевыми словами — id, sub, dlvrd, submit date, done date, stat и err — где stat содержит конечное состояние, такое как DELIVRD, EXPIRED, UNDELIV или REJECTD.