首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 通過串口發送短信(PDU 模式 UCS2 編碼)完整實現

     編輯:PHP 綜合知識

短信編碼模式對比

PDU 結構詳細解析

發送「你好」到 13638197275,中心號 13800571500:

完整 PDU: 0891683180501705F011000D91683136187972F5000800044F60597D

拆解:
08           - 中心號長度(含91) = (2+14)/2 = 8
91           - TON/NPI: 國際號碼格式(+號)
683180501705F0 - 中心號 8613800571500 (奇偶位交換+F補位)
11           - PDU 類型: SMS-SUBMIT
00           - TP-MR: 參考號(0)
0D           - 目標號碼長度: 13位
91           - 目標號碼類型: 國際格式
683136187972F5 - 目標號碼 8613638197275 (奇偶交換+F)
00           - TP-PID: 協議標識
08           - TP-DCS: 數據編碼 UCS2(16-bit)
00           - TP-VP: 有效期(無)
04           - TP-UDL: 用戶數據長度 4字節(2字符×2)
4F60597D     - 內容 "你好" UCS2-BE 編碼

PHP 完整實現代碼

 9600,
    'bits' => 8,
    'stop' => 1,
    'parity' => 0
]);

// Windows 替代: exec('mode COM1: baud=9600 data=8 stop=1 parity=n xon=on');

$smsc = "8613800571500";      // 短信中心號
$send_to = "8613638197275";   // 目標號碼
$text = "你好";                // 短信內容

// 1. 構建 PDU 地址部分
$pdu_addr = '0891' . invertNumbers($smsc);

// 2. 構建 PDU 內容部分
$pdu_text = hex2str(utf82unicode($text));      // 4F60597D
$pdu_text = sprintf("%02X", strlen($pdu_text)/2) . $pdu_text; // 04 + 內容
$pdu_phone = '11000D91' . invertNumbers($send_to) . '000800' . $pdu_text;

// 3. 計算總長度(不含地址部分)
$pdu_len = strlen($pdu_phone) / 2;

// 4. 發送 AT 命令序列
$inter = chr(13);  // 回車
$ctrlz = chr(26);  // Ctrl+Z 結束符

// 設置 PDU 模式
dio_write($fd, "AT+CMGF=0$inter");
// 發送長度
dio_write($fd, "AT+CMGS=$pdu_len$inter");
// 發送 PDU 數據 + 結束符
dio_write($fd, $pdu_addr . $pdu_phone . $ctrlz . $inter);

dio_close($fd);

// ===== 輔助函數 =====
function utf82unicode($str) {
    return iconv("utf-8", "UCS-2BE", $str);
}

function hex2str($hexstring) {
    $str = '';
    for ($i = 0, $len = strlen($hexstring); $i < $len; $i++) {
        $str .= sprintf("%02X", ord($hexstring[$i]));
    }
    return $str;
}

function invertNumbers($msisdn) {
    $len = strlen($msisdn);
    if ($len % 2) $msisdn .= "F";  // 奇數長度補 F
    for ($i = 0; $i < $len; $i += 2) {
        $t = $msisdn[$i];
        $msisdn[$i] = $msisdn[$i+1];
        $msisdn[$i+1] = $t;
    }
    return $msisdn;
}

關鍵點總結

模式編碼最大長度適用場景
Text ModeGSM 7-bit160 字符簡單英文/數字,諾基亞等支援
PDU ModeUCS2 (16-bit)70 字符中文/多語言,通用性最強
PDU Mode8-bit140 字節二進制數據,手機通常不顯示
環節關鍵操作易錯點
號碼處理去+號 → 奇數補F → 奇偶位交換 → 前綴91忘記補F導致長度錯誤
內容編碼UTF-8 → UCS-2BE → 每字節轉兩位十六進制使用 UCS-2LE 導致亂碼
長度計算PDU 字節數(十六進制字符數/2)包含地址部分導致長度超標
AT 命令CMGF=0 → CMGS=長度 → PDU數據 → Ctrl+Z缺少回車符、發送過快

現代替代方案

  • **HTTP 短信網關**:阿里云/騰訊云/網易雲信等 REST API,無需硬件
  • **GSM Modem Pool**:多卡池設備 + HTTP 接口,支援高併發
  • **IoT 卡 + MQTT**:物聯網場景下的數據傳輸替代短信

總結

PDU 模式 UCS2 編碼是短信發送最通用、最兼容的方案。理解其位級結構有助於排查發送失敗、亂碼、長度截斷等疑難問題。現代項目優先選擇雲短信 API,降低硬件維護成本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved