Panoramica
SMPP è un protocollo del settore delle telecomunicazioni, pubblicato per la prima volta da Aldiscon/Logica alla fine degli anni '90 e ora gestito dal forum degli sviluppatori SMPP. Definisce come due peer si scambiano unità discrete chiamate PDU (Protocol Data Units) su una singola connessione TCP: l'applicazione si connette, invia messaggi, riceve conferme, mantiene la connessione attiva e si disconnette. Essendo binario e orientato alla connessione, gestisce carichi di lavoro costanti, con milioni di messaggi al giorno, con un overhead di gran lunga inferiore rispetto all'apertura di una richiesta HTTP per ogni messaggio. Leggete questa pagina dall'inizio alla fine e comprenderete ogni campo di una sessione SMPP reale.
Cos'è SMPP e dove si colloca
Una sessione SMPP ha sempre due ruoli. ESME (External Short Messaging Entity) è la tua applicazione: una piattaforma per SMS di massa, un servizio OTP, un sistema di allerta. L' SMSC (Centro servizi messaggi brevi), chiamato un MC Il Centro Messaggi (Message Centre), nella versione 5.0, è il nodo operatore o aggregatore che memorizza e inoltra i messaggi da e verso i dispositivi mobili sulla rete mobile. L'ESME si connette all'SMSC; l'SMSC si connette alla rete SS7/mobile core più ampia.
SMPP è la spina dorsale di A2P (Messaggistica da applicazione a persona) — codici di verifica, ricevute, avvisi, marketing — in contrapposizione a P2P Scambio di messaggi (da persona a persona) tra due dispositivi mobili. Il traffico A2P è caratterizzato da un elevato volume di messaggi, generati automaticamente e basati sulla conferma di ricezione, esattamente ciò per cui SMPP è stato progettato.
Perché un protocollo TCP binario invece di HTTP? Una singola connessione SMPP è un socket di lunga durata. Una volta aperta, si evita l'handshake TCP e TLS per ogni messaggio, è possibile avere molti messaggi in transito contemporaneamente (finestra asincrona) e l'SMSC invia le conferme di consegna e i messaggi in entrata direttamente sulla stessa connessione. Con un throughput elevato e costante, questo è notevolmente più efficiente di un'API HTTP richiesta/risposta, motivo per cui gli operatori e i grandi mittenti lo adottano come standard.
Cronologia delle versioni
- SMPP v3.3 — la prima versione ampiamente diffusa; ha introdotto il set di PDU principali, ma è precedente ai TLV (parametri opzionali) e al binding del transceiver.
- SMPP v3.4 — la versione dominante attualmente in produzione. Aggiunte le funzionalità di associazione del transceiver, i parametri TLV opzionali, message_payload e data_sm. Quasi tutte le integrazioni reali che realizzerete utilizzano la versione 3.4.
- SMPP v5.0 — la versione più recente. Rinomina SMSC in MC, aggiunge PDU broadcast (broadcast_sm), segnalazione dello stato di congestione e TLV più standardizzati. L'adozione è limitata; si consiglia di supportare prima la v3.4 e di considerare la v5.0 come opzionale.
Architettura e tipi di collegamento
La topologia è semplice: l'ESME apre una connessione TCP all'SMSC/MC e si autentica con un system_id E passwordLa direzione in cui la sessione può trasportare il traffico viene fissata al momento del binding scegliendo una delle tre opzioni. modalità di collegamentoOgni modalità corrisponde a una diversa PDU di binding.
Solo invio. L'ESME può inviare submit_sm ma non può ricevere deliver_sm in questa sessione. Le ricevute devono venire tramite un binding di ricezione separato.
Solo ricezione. L'SMSC invia i messaggi in entrata (messaggi DLR) all'ESME, che non può inviarli in questa sessione.
Entrambe le direzioni in un'unica sessione: submit_sm in uscita, deliver_sm in entrata. Introdotto nella versione 3.4 e impostazione predefinita consigliata per le nuove integrazioni.
Un quarto attore è percorsoL'SMSC decide, per ogni messaggio, quale percorso o interconnessione con l'operatore di destinazione segue il messaggio inviato verso il dispositivo di destinazione, e a quale ESME associato appartiene il messaggio in entrata (originato dal dispositivo mobile).
Sul cavo, SMPP funziona su TCP. La porta predefinita registrata presso IANA è 2775 per connessioni semplici. SMPPS — SMPP incapsulato in TLS — non ha una porta standard univoca; i provider lo espongono su una porta a loro scelta (in pratica si utilizzano le porte 3550, 8775 e 2776). Utilizzare sempre la porta crittografata assegnata dal provider per gli ambienti di produzione.
Il ciclo di vita della sessione
Ogni sessione SMPP segue lo stesso schema: apertura TCP, associazione, mantenimento della connessione, scambio di messaggi e ricevute, quindi disassociazione e chiusura. Il diagramma seguente illustra una sessione completa di un transceiver: ogni riga rappresenta una PDU, il blu indica il flusso dalla ESME all'SMSC, il verde il flusso di ritorno.
Due dettagli importanti. Primo, submit_sm_resp restituisce immediatamente e significa solo "accettato per la consegna" — il risultato reale arriva più tardi come deliver_sm ricevuta. In secondo luogo, ogni richiesta PDU ha una corrispondenza _resp che riecheggia il suo sequence_number, ed è così che le risposte asincrone vengono correlate alle richieste.
Anatomia della PDU
Tutto ciò che si trova su una connessione SMPP è un PDUOgni PDU inizia con un valore fisso Intestazione di 16 byte di quattro interi a 4 byte (32 bit, big-endian), seguiti da un corpo specifico del comando. Leggi prima l'intestazione e saprai esattamente come leggere il resto.
| Offset | Campo | Misurare | Senso |
|---|---|---|---|
| 0–3 | lunghezza_comando | 4 byte | Lunghezza totale dell'intera PDU in ottetti, inclusi header e corpo. |
| 4–7 | command_id | 4 byte | Quale operazione è questa (ad esempio submit_sm = 0x00000004). Le risposte impostano il bit più significativo (0x80000000). |
| 8–11 | stato_comando | 4 byte | 0 nelle richieste; un codice di risultato ESME_R* nelle risposte (0 = ESME_ROK = successo). |
| 12–15 | numero_sequenza | 4 byte | ID assegnato dal chiamante 1…0x7FFFFFFF; la risposta corrispondente lo ripete per correlarli. |
| 16… | corpo | variabile | Parametri obbligatori per questo comando, seguiti da eventuali parametri TLV opzionali. |
Il corpo termina con un numero qualsiasi di TLV — parametri opzionali codificati come Tag (2 byte), Lunghezza (2 byte), Valore (Lunghezza byte). I TLV sono il modo in cui la versione 3.4 ha esteso il protocollo senza compromettere le versioni precedenti: message_payload, receipted_message_id, i campi di concatenazione sar_* e molti altri vengono utilizzati come TLV.
IL numero_sequenza è la chiave per la gestione delle finestre. Poiché SMPP è asincrono, un ESME può inviare molte PDU submit_sm — ciascuna con un sequence_number incrementale — prima che arrivino le risposte. Quando le PDU submit_sm_resp tornano, il loro sequence_number indica a quale invio corrisponde ciascuna. Il numero di PDU non confermate consentite in transito è il dimensione della finestra
Riferimento PDU principali
Queste sono le operazioni che utilizzerete effettivamente. Ogni richiesta ha una PDU di risposta il cui command_id è l'ID della richiesta con il bit più significativo impostato (0x80000000), quindi submit_sm 0x00000004 corrisponde a submit_sm_resp 0x80000004.
| PDU | command_id | Scopo |
|---|---|---|
| bind_receiver | 0x00000001 | Apri una sessione di sola ricezione. |
| bind_transmitter | 0x00000002 | Apri una sessione di solo invio. |
| bind_transceiver | 0x00000009 | Apri una sessione bidirezionale (v3.4). |
| submit_sm | 0x00000004 | Invia un singolo messaggio a una sola destinazione. |
| submit_multi | 0x00000021 | Invia un singolo messaggio a un massimo di 254 destinatari. |
| deliver_sm | 0x00000005 | SMSC → ESME : una ricevuta di consegna o un messaggio in entrata (MO). |
| data_sm | 0x00000103 | Alternativa bidirezionale, utilizzabile solo con TLV, a submit_sm / deliver_sm. |
| query_sm | 0x00000003 | Richiedi SMSC lo stato attuale di un messaggio inviato. |
| cancel_sm | 0x00000008 | Annulla un messaggio precedentemente inviato ma non ancora recapitato. |
| replace_sm | 0x00000007 | Sostituisci il contenuto/la programmazione di un messaggio in sospeso. |
| enquire_link | 0x00000015 | Keepalive: conferma che la sessione sia ancora attiva. |
| unbind | 0x00000006 | Chiudere correttamente la sessione SMPP. |
| generic_nack | 0x80000000 | Risposta negativa per PDU non analizzabile/non valida. |
submit_sm campo per campo
submit_sm è la PDU che invierai più frequentemente. Il suo corpo è una sequenza di parametri obbligatori, seguiti da TLV opzionali. Questi sono i campi che contano nella pratica.
| Campo | Cosa fa |
|---|---|
| service_type | Categoria facoltativa per l'applicazione SMS (ad esempio, vuota o un valore utilizzato dal tuo SMSC per le classi di instradamento/fatturazione). |
| source_addr_ton / _npi | Indicatore del tipo di numero e del piano di numerazione per il mittente. TON 5 = alfanumerico (un ID mittente); TON 1 = internazionale E.164. |
| source_addr | L'indirizzo del mittente: un codice breve, un numero lungo o un ID mittente alfanumerico di massimo 11 caratteri. |
| dest_addr_ton / _npi | TON / NPI per la destinazione. Solitamente TON 1 (internazionale), NPI 1 (ISDN / E.164). |
| destination_addr | Il destinatario MSISDN, normalmente in formato internazionale senza il segno + iniziale. |
| esm_class | Maschera di bit per la modalità/tipo di messaggistica: ad esempio, la richiesta di una ricevuta di consegna viene gestita da registered_delivery, mentre il bit UDHI (0x40) indica che short_message inizia con un UDH. |
| data_coding | Il DCS : 0 = GSM 7 bit (predefinito), 3 = Latin-1, 8 = UCS-2 (Unicode). Determina il limite di caratteri. |
| registered_delivery | Impostare su 1 per richiedere una ricevuta di consegna (deliver_sm) per questo messaggio; 0 per non richiedere alcuna ricevuta. |
| sm_length / short_message | La lunghezza del payload (0–254) e gli ottetti del messaggio stessi, codificati secondo data_coding. |
| message_payload (TLV 0x0424) | TLV opzionale che trasporta il corpo del messaggio al posto di short_message — utilizzato per contenuti lunghi oltre i 254 ottetti. |
| schedule_delivery_time / validity_period | Tempo assoluto/relativo opzionale per programmare la consegna e per quanto tempo l'SMSC deve continuare a ritentare. |
Codifica e concatenazione dei dati
IL data_coding Il campo (lo schema di codifica dei dati, DCS) indica al telefono come interpretare i byte e decide quanti caratteri possono essere contenuti in un SMS.
| codifica dei dati | Codifica | Separare | Concatenato |
|---|---|---|---|
| 0 | Alfabeto predefinito GSM a 7 bit | 160 caratteri | 153 caratteri / parte |
| 3 | Latino-1 (ISO-8859-1), 8 bit | 140 caratteri | 134 caratteri / parte |
| 8 | UCS-2 (UTF-16BE) — Unicode | 70 caratteri | 67 caratteri / parte |
Un messaggio più lungo di un segmento viene diviso e riassemblato sul telefono utilizzando un UDH (User Data Header) anteposto a ciascuna parte. L'elemento di concatenazione utilizza IEI 0x00 (Riferimento a 8 bit) — un'intestazione di 6 ottetti contenente un numero di riferimento, il numero totale di componenti e l'indice di questo componente. Questi 6 ottetti sono il motivo per cui i limiti per componente si riducono a 153 (GSM a 7 bit) e 67 (UCS-2). Quando si invia un UDH all'interno di short_message, è necessario impostare anche il bit UDHI (0x40) in esm_class.
Esistono due modi per inviare contenuti lunghi: creare autonomamente le parti segmentate UDH (ciascuna un submit_sm con UDHI impostato), oppure consegnare l'intero corpo all'SMSC nel message_payload TLV e lascia che si segmenti. Alcuni SMSC, invece, accettano i TLV sar_msg_ref_num / sar_total_segments / sar_segment_seqnum per descrivere la concatenazione senza un UDH.
Ricevute di consegna (DLR)
Quando imposti registered_delivery = 1, l'SMSC in seguito comunica l'esito del messaggio inviandoti un deliver_sm con il bit di ricevuta di consegna impostato in esm_class (0x04Il testo della ricevuta è presente nel campo short_message come stringa di parole chiave predefinita:
id:1a2b3c4d5e sub:001 dlvrd:001 submit date:2607251432 done date:2607251432 stat:DELIVRD err:000 text:Your code is 8IL id corrisponde al message_id che hai ricevuto in risposta in submit_sm_resp (e anche nel TLV receipted_message_id 0x001E). stat Il campo contiene lo stato finale:
| statistica | Senso |
|---|---|
| DELIVRD | Consegnato al telefono. Stato di successo. |
| EXPIRED | Il periodo di validità è scaduto prima della consegna: l'SMSC ha interrotto i tentativi di invio. |
| DELETED | Il messaggio è stato eliminato sull'SMSC. |
| UNDELIV | Impossibile consegnare: nessun percorso di consegna o il telefono non è raggiungibile. |
| ACCEPTD | Accettato (ad esempio letto manualmente SMSC) — uno stato intermedio. |
| UNKNOWN | L' SMSC non dispone di informazioni sullo stato per il messaggio. |
| REJECTD | Rifiutato SMSC o da una rete a valle (ad esempio, mittente bloccato). |
Rispondi sempre a deliver_sm con un deliver_sm_respIn caso contrario, l'SMSC invierà nuovamente la ricevuta e potrebbe limitare la velocità o interrompere la connessione. Si noti che la formattazione della ricevuta non è perfettamente standardizzata: i provider variano leggermente nell'ordine dei campi e nella mappatura dei codici di errore.
Codici di errore/stato del comando
Ogni PDU di risposta contiene un command_status nella sua intestazione — un ESME_R* Codice. Zero significa successo; qualsiasi altro valore indica il motivo del rifiuto della richiesta. Questi sono i codici che incontrerai più frequentemente.
| Codice | Valore | Senso |
|---|---|---|
| ESME_ROK | 0x00000000 | Nessun errore: successo. |
| ESME_RINVMSGLEN | 0x00000001 | Lunghezza del messaggio non valida (problema sm_length /payload). |
| ESME_RINVCMDLEN | 0x00000002 | command_length non valida: la struttura PDU è errata. |
| ESME_RINVCMDID | 0x00000003 | command_id sconosciuto o non supportato. |
| ESME_RINVBNDSTS | 0x00000004 | Comando non valido nello stato di associazione corrente (ad esempio, invio su un'associazione RX). |
| ESME_RALYBND | 0x00000005 | ESME è già vincolato. |
| ESME_RINVSRCADR | 0x0000000A | Indirizzo sorgente (ID mittente) non valido. |
| ESME_RINVDSTADR | 0x0000000B | Indirizzo di destinazione non valido. |
| ESME_RBINDFAIL | 0x0000000D | Connessione non riuscita: system_id / password errati. |
| ESME_RINVPASWD | 0x0000000E | Password non valida. |
| ESME_RTHROTTLED | 0x00000058 | Errore di limitazione della velocità: hai superato il numero di messaggi consentito. |
| ESME_RSUBMITFAIL | 0x00000045 | submit_sm / submit_multi non riuscito. |
| ESME_RSYSERR | 0x00000008 | Errore di sistema SMSC. |
Il registro completo, comprese le gamme di fornitori specifiche per ciascun provider, è consultabile nel Riferimento ai codici di errore SMPP
Throughput, finestratura e limitazione
La velocità di trasmissione in SMPP è misurata in TPS — transazioni (submit_sm) al secondo — ed è regolato da due fattori: la velocità consentita dall'SMSC e il numero di messaggi che mantieni in transito. Poiché SMPP è asincrono, non è necessario attendere ogni submit_sm_resp prima di inviare la PDU successiva. Il numero di invii non confermati che consenti contemporaneamente è il tuo dimensione della finestra (generalmente 10-100). Una finestra più ampia nasconde la latenza di andata e ritorno e aumenta il TPS effettivo, fino al limite massimo dell'SMSC.
- Rispetta l'acceleratore. Quando l'SMSC restituisce ESME_RTHROTTLED (0x58), fai un passo indietro: metti in pausa e riprova con un backoff esponenziale invece di insistere con il bind, che potrebbe causare la disconnessione.
- Mantieniti in vita con una cadenza regolare. Invia il link di richiesta all'incirca ogni 30 secondi quando il server è inattivo; se alcuni messaggi rimangono senza risposta, si presume che il link non funzioni.
- Riconnettiti intenzionalmente. In caso di disconnessione, riconnettersi e riassociare con backoff e jitter; non utilizzare il tight-loop. Monitorare i numeri di sequenza in sospeso per poter riconciliare le ricevute dopo una riconnessione.
- Scalare con i vincoli, con attenzione. Un TPS aggregato più elevato deriva solitamente da più connessioni, ma solo fino al limite autorizzato dal provider per ciascun account.
Esempio di codice
Un esempio illustrativo del flusso di connessione → associazione → invio in pseudocodice in stile Node.js. Le librerie SMPP reali (ad esempio, node-smpp, jSMPP per Java o python-smpplib) gestiscono automaticamente la codifica PDU; questo esempio mostra la struttura della sessione, non l'API di una libreria specifica.
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 gestisce un gateway SMSC di livello carrier che accetta connessioni SMPP v3.4 su TLS. Offre: connessione transceiver, elevato numero di transazioni al secondo (TPS) con finestra asincrona, conferme di consegna complete, supporto Unicode e concatenazione, e una connessione con credenziali e accesso IP consentito per raggiungere operatori in tutto il mondo. Si tratta dello stesso protocollo descritto in questa pagina, ma applicato a percorsi reali.
Richiedi un binding per il tuo account e il nostro team di ingegneri commerciali configurerà il tuo system_id, l'endpoint TLS, il TPS e la lista IP consentita. In alternativa, puoi leggere come è configurato il gateway.
Domande frequenti
Quale porta utilizza SMPP?
La porta predefinita registrata presso IANA è la 2775 TCP per SMPP non crittografato. Non esiste un'unica porta TLS standard: SMPP (SMPP su TLS) viene comunemente eseguito su una porta specifica del provider, come la 3550, la 8775 o la 2776, quindi è sempre necessario utilizzare la porta assegnata dall'operatore SMSC. BroadNet pubblica il proprio host di binding, la porta non crittografata e la porta TLS insieme alle credenziali.
Qual è la differenza tra submit_sm e data_sm?
submit_sm è la PDU principale utilizzata da un ESME per inviare un singolo messaggio breve; contiene il classico campo short_message (fino a 254 ottetti) più TLV opzionali. data_sm è un'alternativa semplificata e simmetrica introdotta in SMPP v3.4 che contiene sempre il contenuto del TLV message_payload e può fluire in entrambe le direzioni (ESME→SMSC o SMSC→ESME). La maggior parte del traffico A2P utilizza submit_sm; data_sm viene utilizzato quando è preferibile la sua struttura bidirezionale basata esclusivamente su TLV.
Come gestisce SMPP Unicode?
I dati Unicode vengono inviati impostando data_coding a 8 (UCS-2 / UTF-16BE big-endian). Un singolo segmento UCS-2 contiene 70 caratteri; le parti UCS-2 concatenate contengono 67 caratteri ciascuna, poiché 6 ottetti vengono utilizzati dall'intestazione di concatenazione UDH. Il formato GSM a 7 bit (data_coding 0) è l'impostazione predefinita per il testo latino di base a 160/153 caratteri.
Che cos'è un'associazione tra ricetrasmettitore e ricevitore?
Un binding transceiver (TRX) è una singola sessione SMPP, aperta con bind_transceiver, che può sia inviare messaggi (submit_sm) che ricevere messaggi e conferme di consegna (deliver_sm) sulla stessa connessione TCP. Sostituisce il vecchio modello di apertura di binding trasmettitore e ricevitore separati ed è la modalità consigliata per la maggior parte delle integrazioni moderne.
Perché utilizzare SMPP anziché un'API HTTP?
SMPP è un protocollo TCP binario persistente, progettato per un throughput elevato e costante. Un binding di lunga durata evita gli handshake TLS/TCP per ogni messaggio, supporta la gestione asincrona delle finestre (molti messaggi submit_sm in sospeso prima di una conferma) e recapita in tempo reale le ricevute deliver_sm e i messaggi provenienti da dispositivi mobili tramite lo stesso socket. Per volumi A2P molto elevati e costanti, è più efficiente del protocollo HTTP richiesta/risposta; HTTP REST è più semplice per volumi inferiori e canali più complessi.
Cos'è enquire_link?
enquire_link è una PDU keepalive leggera che uno dei peer invia per confermare che la sessione SMPP e la connessione TCP sottostante siano ancora attive; l'altro lato risponde con enquire_link_resp. Viene tipicamente inviata ogni 30 secondi durante i periodi di inattività. Se diversi enquire_link rimangono senza risposta, il peer considera il collegamento interrotto e si riconnette.
Che significato ha il campo command_length nell'intestazione di una PDU?
`command_length` è il primo campo di 4 byte di ogni intestazione PDU SMPP e contiene la lunghezza totale dell'intera PDU in ottetti, inclusa l'intestazione stessa di 16 byte e l'intero corpo. Un ricevitore legge prima questi 4 byte per sapere esattamente quanti altri byte leggere per la PDU completa prima di analizzare `command_id`, `command_status` e `sequence_number`.
Che cos'è una ricevuta di consegna (DLR) in SMPP?
Una ricevuta di consegna è il messaggio con cui l'SMSC comunica all'ESME l'esito finale di un messaggio inviato. Arriva come PDU deliver_sm con il bit di ricevuta di consegna esm_class impostato (0x04). Il messaggio breve contiene una stringa di ricevuta con parole chiave: id, sub, dlvrd, data di invio, data di completamento, stat ed err, dove stat indica lo stato finale, ad esempio DELIVRD, EXPIRED, UNDELIV o REJECTD.