Aperçu
SMPP est un protocole de l'industrie des télécommunications, initialement publié par Aldiscon/Logica à la fin des années 1990 et désormais maintenu par le forum des développeurs SMPP. Il définit comment deux pairs échangent des unités discrètes appelées PDU (Protocol Data Units) via une connexion TCP unique : l'application se lie, envoie des messages, reçoit les accusés de réception, maintient la connexion active et se délie. Étant binaire et orienté connexion, il gère des charges de travail stables, de l'ordre du million de messages par jour, avec une surcharge bien moindre que l'ouverture d'une requête HTTP par message. Lisez cette page en entier pour comprendre chaque champ d'une session SMPP réelle.
Qu'est-ce qu'un SMPP et où s'applique-t-il ?
Une session SMPP comporte toujours deux rôles. L'ESME (External Short Messaging Entity) est votre application — une plateforme de SMS en masse, un service OTP, un système d'alerte. Le SMSC (Short Message Service Centre), appelé MC (Message Centre) dans la v5.0, est le nœud de l'opérateur ou de l'agrégateur qui stocke et retransmet les messages vers et depuis les terminaux via le réseau mobile. L'ESME se connecte au SMSC ; le SMSC se connecte au réseau SS7 / cœur de réseau mobile.
SMPP est l'épine dorsale de A2P (Application-Personne) Messagerie — codes de vérification, reçus, alertes, marketing — par opposition à P2P Messagerie texte (de personne à personne) entre deux téléphones portables. A2P Le trafic est volumineux, généré automatiquement et repose sur la confirmation de livraison, ce qui correspond exactement à ce pour quoi le protocole SMPP a été conçu.
Pourquoi un protocole TCP binaire plutôt que HTTP ? Une seule liaison SMPP correspond à une socket persistante. Une fois ouverte, vous évitez une négociation TCP et TLS par message, vous pouvez gérer plusieurs messages simultanément (fenêtre asynchrone), et le SMSC renvoie les accusés de réception et les messages entrants directement sur la même connexion. À haut débit soutenu, cette méthode est nettement plus efficace qu'une API HTTP requête/réponse ; c'est pourquoi les opérateurs et les grands expéditeurs l'adoptent comme standard.
Historique des versions
- SMPP v3.3 — la première version largement déployée ; elle a introduit l’ensemble de PDU de base, mais elle est antérieure aux TLV (paramètres optionnels) et à la liaison de l’émetteur-récepteur.
- SMPP v3.4 — la version dominante en production aujourd'hui. Ajout de la liaison de l'émetteur-récepteur, des paramètres TLV optionnels, de message_payload et de data_sm. Presque toutes les intégrations concrètes que vous développerez utilisent la version 3.4.
- SMPP v5.0 — La toute dernière version. Elle renomme SMSC en MC et ajoute : les PDU de diffusion (broadcast_sm), la signalisation de l’état de congestion et davantage de TLV standardisés. Son adoption est limitée ; privilégiez d’abord la version 3.4 et considérez la version 5.0 comme optionnelle.
Architecture et types de liaison
La topologie est simple : l’ESME ouvre une connexion TCP avec le SMSC/MC et s’authentifie. system_id et passwordLa direction dans laquelle la session est autorisée à acheminer le trafic est fixée lors de la liaison en choisissant l'une des trois options suivantes : modes de liaisonChaque mode correspond à une PDU de liaison différente.
Soumission uniquement. L'ESME peut envoyer des requêtes submit_sm mais ne peut pas recevoir de requêtes deliver_sm lors de cette session. Les accusés de réception doivent être reçus via une liaison de réception distincte.
Réception uniquement. Le SMSC transmet les messages entrants (deliver_sm) à l'ESME, qui ne peut pas émettre de messages lors de cette session.
Les deux sens sont pris en charge au cours d'une même session : envoi de submit_sm, réception de deliver_sm. Introduit dans la version 3.4 et conformité par défaut recommandée pour les nouvelles intégrations.
Un quatrième acteur est routageLe SMSC détermine, pour chaque message, la route ou l'interconnexion en aval qu'emprunte un message soumis vers le terminal de destination, et à quel ESME lié appartient un message entrant (d'origine mobile).
Sur le réseau, le protocole SMPP utilise TCP. Le port par défaut enregistré auprès de l'IANA est : 2775 pour les connexions simples. SMPPS Le protocole SMPP chiffré avec TLS ne possède pas de port standard unique ; les fournisseurs l'exposent sur un port de leur choix (3550, 8775 et 2776 sont couramment utilisés). Utilisez toujours le port chiffré attribué par votre fournisseur pour la production.
Le cycle de vie de la session
Chaque session SMPP suit le même cycle : ouverture du protocole TCP, liaison, maintien de la connexion, échange de messages et d’accusés de réception, puis déconnexion et fermeture. Le schéma ci-dessous illustre une session complète d’émetteur-récepteur : chaque ligne représente une PDU, en bleu de l’ESME vers le SMSC, en vert pour le retour.
Deux détails importants. Premièrement, submit_sm_resp Le retour est immédiat et signifie seulement « accepté pour livraison » — le résultat final arrive plus tard. deliver_sm reçu. Deuxièmement, chaque PDU de requête a une correspondance _resp qui fait écho à son sequence_number, c'est ainsi que les réponses asynchrones sont mises en relation avec les requêtes.
Anatomie du PDU
Tout sur une connexion SMPP est un PDUChaque PDU commence par une valeur fixe En-tête de 16 octets de quatre entiers de 4 octets (32 bits, big-endian), suivis d'un corps spécifique à la commande. Lisez d'abord l'en-tête et vous saurez exactement comment lire le reste.
| Compenser | Champ | Taille | Signification |
|---|---|---|---|
| 0–3 | longueur_commande | 4 octets | Longueur totale de l'ensemble du PDU en octets, en-tête + corps inclus. |
| 4–7 | command_id | 4 octets | À quelle opération cela correspond-il (par exemple, submit_sm = 0x00000004) ? Les réponses positionnent le bit de poids fort à 0x80000000. |
| 8–11 | statut_commande | 4 octets | 0 dans les requêtes ; un code de résultat ESME_R* dans les réponses (0 = ESME_ROK = succès). |
| 12–15 | numéro_de_séquence | 4 octets | L'appelant a reçu un identifiant 1…0x7FFFFFFF ; la réponse correspondante le renvoie pour les corréler. |
| 16… | corps | variable | Paramètres obligatoires pour cette commande, puis tous les paramètres TLV optionnels. |
Le corps se termine par un nombre quelconque de TLV — Paramètres optionnels encodés sous forme de Tag (2 octets), Longueur (2 octets), Valeur (Longueur en octets). Les TLV permettent à la version 3.4 d'étendre le protocole sans impacter la compatibilité avec les versions précédentes : message_payload, receipted_message_id, les champs de concaténation sar_* et bien d'autres tous ces éléments sont gérés par des TLV.
Le numéro_de_séquence est la clé du fenêtrage. Étant donné que SMPP est asynchrone, un ESME peut envoyer plusieurs PDU submit_sm — chacune avec un numéro de séquence incrémenté — avant la réception de toute réponse. Lorsque les PDU submit_sm_resp reviennent, leur numéro de séquence indique à quelle soumission chacune répond. Le nombre de PDU non acquittés autorisés en transit est le taille de la fenêtre.
Référence des PDU de base
Voici les opérations que vous utiliserez concrètement. Chaque requête possède une PDU de réponse dont l'identifiant de commande (command_id) correspond à l'identifiant de la requête avec le bit de poids fort activé (0x80000000). Ainsi, submit_sm 0x00000004 est associé à submit_sm_resp 0x80000004.
| PDU | command_id | But |
|---|---|---|
| bind_receiver | 0x00000001 | Ouvrez une session en réception seule. |
| bind_transmitter | 0x00000002 | Ouvrir une session en mode soumission uniquement. |
| bind_transceiver | 0x00000009 | Ouvrir une session bidirectionnelle (v3.4). |
| submit_sm | 0x00000004 | Envoyer un seul message à une seule destination. |
| submit_multi | 0x00000021 | Envoyez un message à un maximum de 254 destinataires. |
| deliver_sm | 0x00000005 | SMSC → ESME : un accusé de réception ou un message entrant (MO). |
| data_sm | 0x00000103 | Alternative bidirectionnelle TLV uniquement à submit_sm / deliver_sm. |
| query_sm | 0x00000003 | Demandez au SMSC l'état actuel d'un message soumis. |
| cancel_sm | 0x00000008 | Annuler un message précédemment envoyé mais non encore distribué. |
| replace_sm | 0x00000007 | Remplacer le contenu/la planification d'un message en attente. |
| enquire_link | 0x00000015 | Keepalive — vérifiez que la session est toujours active. |
| unbind | 0x00000006 | Fermez proprement la session SMPP. |
| generic_nack | 0x80000000 | Accusé de réception négatif pour une PDU non analysable/invalide. |
submit_sm champ par champ
submit_sm Il s'agit du PDU que vous enverrez le plus souvent. Son corps est une séquence de paramètres obligatoires, puis de TLV optionnels. Ce sont ces champs qui importent en pratique.
| Champ | Ce que cela fait |
|---|---|
| service_type | Catégorie d'application SMS facultative (par exemple, vide ou une valeur que votre SMSC utilise pour les classes de routage/facturation). |
| source_addr_ton / _npi | Type de numéro et indicateur de plan de numérotation pour l'expéditeur. TON 5 = alphanumérique (un identifiant d'expéditeur) ; TON 1 = international E.164. |
| source_addr | L'adresse de l'expéditeur — un code court, un numéro long ou un identifiant d'expéditeur alphanumérique de 11 caractères maximum. |
| dest_addr_ton / _npi | TON / NPI pour la destination. Habituellement TON 1 (international), NPI 1 (ISDN / E.164). |
| destination_addr | Le MSISDN du destinataire, normalement au format international sans + initial. |
| esm_class | Masque de bits du mode/type de messagerie — par exemple, la demande d'un accusé de réception est gérée par registered_delivery, tandis que le bit UDHI (0x40) indique que short_message commence par un UDH. |
| data_coding | Le DCS : 0 = GSM 7 bits (par défaut), 3 = Latin-1, 8 = UCS-2 (Unicode). Détermine la limite de caractères. |
| registered_delivery | Indiquez la valeur 1 pour demander un accusé de réception (deliver_sm) pour ce message ; 0 pour aucune demande d’accusé de réception. |
| sm_length / short_message | La longueur de la charge utile (0–254) et les octets du message eux-mêmes, encodés selon data_coding. |
| message_payload (TLV 0x0424) | TLV optionnel transportant le corps du message au lieu de short_message — utilisé pour les contenus longs dépassant 254 octets. |
| schedule_delivery_time / validity_period | Délai absolu/relatif optionnel pour programmer la livraison et durée pendant laquelle le SMSC doit réessayer. |
Codage et concaténation des données
Le data_coding Le champ (le schéma de codage des données, DCS) indique au combiné comment interpréter les octets et détermine le nombre de caractères contenus dans un SMS. SMS
| codage des données | Codage | Célibataire | Concaténé |
|---|---|---|---|
| 0 | Alphabet GSM 7 bits par défaut | 160 caractères | 153 caractères / partie |
| 3 | Latin-1 (ISO-8859-1), 8 bits | 140 caractères | 134 caractères / partie |
| 8 | UCS-2 (UTF-16BE) — Unicode | 70 caractères | 67 caractères / partie |
Un message de plus d'un segment est divisé puis réassemblé sur le combiné à l'aide d'un UDH (En-tête de données utilisateur) ajouté au début de chaque partie. L'élément de concaténation utilise IEI 0x00 (8 bits référence) — un en-tête de 6 octets contenant un numéro de référence, le nombre total de parties et l'index de cette partie. Ces 6 octets expliquent pourquoi les limites par partie tombent à 153 (GSM 7 bits) et 67 (UCS-2). Lorsque vous envoyez un UDH dans short_message, vous devez également activer le bit UDHI (0x40) dans esm_class.
Il existe deux façons d'envoyer du contenu long : soit créer vous-même les parties segmentées UDH (chacune étant un submit_sm avec un ensemble UDHI), soit transmettre le corps entier au SMSC dans le message_payload TLV et laissez-le segmenter. Certains SMSC acceptent plutôt les TLV sar_msg_ref_num / sar_total_segments / sar_segment_seqnum pour décrire la concaténation sans UDH.
Accusés de réception (DLR)
Lorsque vous définissez registered_delivery = 1, le SMSC vous informe ultérieurement du sort du message en vous envoyant un deliver_sm avec le bit de réception de livraison défini dans esm_class (0x04Le texte du reçu se trouve dans le champ short_message sous forme de chaîne de caractères générique :
id:1a2b3c4d5e sub:001 dlvrd:001 submit date:2607251432 done date:2607251432 stat:DELIVRD err:000 text:Your code is 8Le id correspond à l'identifiant de message que vous avez reçu en retour dans submit_sm_resp (également affiché dans le TLV receipted_message_id 0x001E). stat Le champ indique l'état final :
| stat | Signification |
|---|---|
| DELIVRD | Livré au combiné. État de réussite. |
| EXPIRED | Le délai de validité a expiré avant la livraison — le SMSC a cessé d'essayer de nouveau. |
| DELETED | Le message a été supprimé au niveau du SMSC. |
| UNDELIV | Non distribuable — aucune route ou téléphone injoignable. |
| ACCEPTD | Accepté (par exemple lu manuellement sur le SMSC) — un état intermédiaire. |
| UNKNOWN | Le SMSC ne dispose d'aucune information d'état pour ce message. |
| REJECTD | Rejeté par le SMSC ou un réseau en aval (par exemple, expéditeur bloqué). |
Répondez toujours à un deliver_sm par un deliver_sm_respSi vous ne le faites pas, le SMSC, renverra le reçu et pourra limiter ou interrompre la liaison. Veuillez noter que le format des reçus n'est pas parfaitement standardisé : l'ordre des champs et la correspondance des codes d'erreur varient légèrement d'un fournisseur à l'autre.
Codes d'erreur / d'état de commande
Chaque PDU de réponse transporte un command_status dans son en-tête — un ESME_R* Le code zéro signifie succès ; toute autre valeur explique pourquoi la requête a été refusée. Ce sont les cas les plus fréquents.
| Code | Valeur | Signification |
|---|---|---|
| ESME_ROK | 0x00000000 | Aucune erreur — succès. |
| ESME_RINVMSGLEN | 0x00000001 | Longueur du message invalide (problème sm_length / payload). |
| ESME_RINVCMDLEN | 0x00000002 | command_length invalide — le formatage PDU est incorrect. |
| ESME_RINVCMDID | 0x00000003 | command_id inconnu ou non pris en charge. |
| ESME_RINVBNDSTS | 0x00000004 | Commande non valide dans l'état de liaison actuel (par exemple, soumission sur une liaison RX). |
| ESME_RALYBND | 0x00000005 | ESME est déjà lié. |
| ESME_RINVSRCADR | 0x0000000A | Adresse source invalide (ID de l'expéditeur). |
| ESME_RINVDSTADR | 0x0000000B | Adresse de destination invalide. |
| ESME_RBINDFAIL | 0x0000000D | Échec de la liaison — system_id / mot de passe incorrect. |
| ESME_RINVPASWD | 0x0000000E | Mot de passe invalide. |
| ESME_RTHROTTLED | 0x00000058 | Erreur de limitation de débit — vous avez dépassé le débit de messages autorisé. |
| ESME_RSUBMITFAIL | 0x00000045 | Échec submit_sm / submit_multi. |
| ESME_RSYSERR | 0x00000008 | Erreur système SMSC. |
Le registre complet, y compris les gammes de fournisseurs spécifiques à chaque prestataire, est consultable dans le Référence des codes d'erreur SMPP
Débit, fenêtrage et limitation
Le débit en SMPP est mesuré en TPS — transactions (submit_sm) par seconde — et ce débit est régi par deux facteurs : le débit autorisé par le SMSC et le nombre de messages en transit. Comme SMPP est asynchrone, vous n’avez pas besoin d’attendre chaque réponse submit_sm_resp avant d’envoyer le PDU suivant. Le nombre de soumissions non acquittées autorisées simultanément est votre taille de la fenêtre (généralement de 10 à 100). Une fenêtre plus large masque la latence aller-retour et augmente le TPS effectif, jusqu'au plafond du SMSC.
- Respectez l'accélérateur. Lorsque le SMSC renvoie ESME_RTHROTTLED (0x58), il est conseillé de patienter : faites une pause et réessayez avec un délai exponentiel plutôt que de solliciter fortement la connexion ce qui pourrait entraîner une déconnexion.
- Restez en vie à un rythme régulier. Envoyer enquire_link environ toutes les 30 secondes en cas d'inactivité ; si plusieurs requêtes restent sans réponse, considérer que le lien est rompu.
- Reconnectez-vous délibérément. En cas de déconnexion, reconnectez-vous et rétablissez la liaison avec un délai d'attente et une gigue ; n'effectuez pas de boucle serrée. Suivez les numéros de séquence en attente afin de pouvoir rapprocher les reçus après une reconnexion.
- Montez en charge avec plusieurs binds, avec précaution. Un TPS agrégé plus élevé provient généralement de plusieurs liaisons, mais seulement dans la limite autorisée par votre fournisseur par compte.
Exemple de code
Un exemple de flux de connexion → liaison → soumission en pseudocode de type Node. Les bibliothèques SMPP réelles (par exemple, node-smpp, jSMPP pour Java ou python-smpplib) gèrent l'encodage des PDU ; cet exemple illustre la structure de la session, et non l'API d'une bibliothèque spécifique.
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 exploite une passerelle SMSC de qualité opérateur qui accepte les liaisons SMPP v3.4 via TLS. Vous bénéficiez ainsi : de liaisons d'émetteur-récepteur, d'un débit TPS élevé avec fenêtrage asynchrone, d'accusés de réception complets, de la prise en charge Unicode et de la concaténation, et d'une connexion autorisée par liste blanche IP pour joindre les opérateurs du monde entier. Il s'agit du même protocole que celui présenté sur cette page, configuré pour des routes réelles.
Demandez une liaison pour votre compte et notre équipe d'ingénierie commerciale configurera votre identifiant système, votre point de terminaison TLS, votre TPS et votre liste blanche d'adresses IP. Vous pouvez également consulter la documentation relative à la conception de la passerelle.
Foire aux questions
Quel port utilise le protocole SMPP ?
Le port TCP par défaut enregistré auprès de l'IANA pour le protocole SMPP est le 2775. Il n'existe pas de port TLS standard unique ; le protocole SMPPS (SMPP sur TLS) utilise généralement un port spécifique au fournisseur, tel que 3550, 8775 ou 2776. Il est donc impératif d'utiliser le port attribué par votre opérateur SMSC. BroadNet publie son hôte de liaison, son port SMPP et son port TLS avec vos identifiants.
Quelle est la différence entre submit_sm et data_sm ?
Le PDU `submit_sm` est le principal PDU utilisé par un ESME pour soumettre un message court unique ; il contient le champ `short_message` classique (jusqu'à 254 octets) ainsi que des TLV optionnels. `data_sm` est une alternative simplifiée et symétrique introduite dans SMPP v3.4 qui transporte toujours le contenu du TLV `message_payload` et peut circuler dans les deux sens (ESME→SMSC ou SMSC→ESME). La plupart du trafic A2P utilise `submit_sm` ; `data_sm` est utilisé lorsque sa structure bidirectionnelle, avec uniquement des TLV, est préférable.
Comment le protocole SMPP gère-t-il l'Unicode ?
L'Unicode est transmis en définissant data_coding sur 8 (UCS-2 / UTF-16BE big-endian). Un segment UCS-2 contient 70 caractères ; la concaténation de segments UCS-2 contient 67 caractères chacun, car 6 octets sont utilisés par l'en-tête de concaténation UDH. Le GSM 7 bits (data_coding 0) est le format par défaut pour les textes latins de base (160/153 caractères).
Qu'est-ce qu'une liaison émetteur-récepteur ?
Une liaison TRX (émetteur-récepteur) correspond à une session SMPP unique, ouverte avec la commande `bind_transceiver`, permettant à la fois l'envoi (`submit_sm`) et la réception (avec accusés de réception) de messages via une même connexion TCP. Elle remplace l'ancien modèle consistant à ouvrir des liaisons distinctes pour l'émetteur et le récepteur, et constitue le mode recommandé pour la plupart des intégrations modernes.
Pourquoi utiliser SMPP plutôt qu'une API HTTP ?
SMPP est un protocole TCP binaire persistant conçu pour un débit élevé et soutenu. Une liaison de longue durée évite les échanges TLS/TCP par message, prend en charge le fenêtrage asynchrone (plusieurs requêtes submit_sm en attente avant un accusé de réception) et transmet en temps réel les accusés de réception deliver_sm et les messages émis par le mobile via le même socket. Pour des volumes A2P très élevés et stables, il est plus efficace que le protocole HTTP requête/réponse ; HTTP REST est plus simple pour des volumes plus faibles et des canaux plus riches.
Qu'est-ce que enquire_link ?
Enquire_link est une PDU de maintien de connexion légère qu'un pair envoie pour confirmer que la session SMPP et la connexion TCP sous-jacente sont toujours actives ; l'autre pair répond par Enquire_link_resp. Elle est généralement envoyée toutes les 30 secondes en période d'inactivité. Si plusieurs Enquire_link restent sans réponse, le pair considère la connexion comme interrompue et se reconnecte.
Que signifie command_length dans un en-tête PDU ?
Le champ `command_length`, composé des 4 premiers octets de l'en-tête de chaque PDU SMPP, indique la longueur totale du PDU en octets, incluant l'en-tête de 16 octets et le corps du message. Le récepteur lit d'abord ces 4 octets pour déterminer le nombre d'octets restants à lire pour obtenir le PDU complet, avant d'analyser `command_id`, `command_status` et `sequence_number`.
Qu'est-ce qu'un accusé de réception de livraison (DLR) dans SMPP ?
Un accusé de réception est un message envoyé par le SMSC à l'ESME indiquant le sort final d'un message soumis. Il arrive sous la forme d'une PDU deliver_sm dont le bit delivery-receipt de la classe ESM est activé (0x04). Le short_message contient une chaîne de caractères contenant les mots clés suivants : id, sub, dlvrd, date de soumission, date de traitement, stat et err. stat indique l'état final, par exemple : DELIVRD, EXPIRED, UNDELIV ou REJECTD.