You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel项目中SMPP协议认证失败问题求助

Laravel中SMPP协议认证失败问题排查与解决

我在Laravel项目中使用SMPP协议发送短信,已成功与服务器建立Socket连接,但使用正确信息认证时失败。服务器返回过两种错误:

  • 一种是:Authentication failed. Server response: �
  • 另一种是:Server response:\x00\x00\x00\x10€\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00"

我使用php-smpp库,以下是负责创建Socket和服务器认证的控制器代码:

<?php

namespace App\Http\Controllers;
use SMPP;
use Exception;
use GsmEncoder;
use SmppClient;
use SmppAddress;
use SocketTransport;
use Illuminate\Support\Facades\Log;


class apiSmsSmppController extends Controller {
    function sendSmsSmpp($message, $to) {
        $host = 'xxx.xxx.xx.xx';
        $port = xxxx;
        $from = "Net4Work";
        $systemId = "xxxxxx";
        $password = "xxxxxx";
        

        // Création de la socket
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

        if ($socket === false) {
            // Gestion de l'erreur
            $error = socket_strerror(socket_last_error());
            die("Failed to create socket: $error");
        }

        // Connexion à la socket du serveur
        $result = socket_connect($socket, $host, $port);

        if ($result === false) {
            // Gestion de l'erreur
            $error = socket_strerror(socket_last_error($socket));
            die("Failed to connect to $host:$port: $error");
        }

        // La connexion a réussi
        //echo "Connected to $host:$port";

        // Envoi des informations d'authentification au serveur
        $authData = pack('a'.strlen($systemId).'ca'.strlen($password).'ca1', $systemId, 0x02, $password, 0x00, 0x00);
        $result = socket_write($socket, $authData, strlen($authData));

        if ($result === false) {
            // Gestion de l'erreur
            $error = socket_strerror(socket_last_error($socket));
            die("Failed to send authentication data: $error");
        }

        // Réception de la réponse du serveur
        $response = socket_read($socket, 1024);
        if ($response === false) {
            // Gestion de l'erreur
            $error = socket_strerror(socket_last_error($socket));
            die("Failed to receive server response: $error");
        }

        // Vérification de la réponse du serveur pour confirmer l'authentification
        $commandStatus = unpack('N', substr($response, 4, 4))[1];

        if ($commandStatus !== 0x00000000) {
            // L'authentification a échoué
            die("Authentication failed. Server response: $response");
        }

        // L'authentification a réussi
        dd("Authentication successful. Server response: $response");

    }
}

问题根源

你手动封装认证数据包的方式不符合SMPP协议规范,bind请求有严格的结构定义,手动pack的格式错误导致服务器无法解析认证信息。另外,你已经引入了php-smpp库的封装类,却手动操作Socket,完全浪费了库的封装能力,也容易出错。

修正后的代码

直接使用php-smpp库提供的标准方法建立连接和认证:

<?php

namespace App\Http\Controllers;
use Exception;
use SmppClient;
use SmppAddress;
use SocketTransport;
use Illuminate\Support\Facades\Log;

class apiSmsSmppController extends Controller {
    function sendSmsSmpp($message, $to) {
        $host = 'xxx.xxx.xx.xx';
        $port = xxxx;
        $from = "Net4Work";
        $systemId = "xxxxxx";
        $password = "xxxxxx";

        // 使用库的SocketTransport创建连接
        $transport = new SocketTransport([$host], $port);
        $transport->setRecvTimeout(10000); // 设置超时时间(毫秒)
        $transport->open();

        // 初始化SmppClient
        $smpp = new SmppClient($transport);
        $smpp->setDebug(true); // 开启调试,便于排查问题

        try {
            // 执行认证(根据服务器要求选择bind类型:transmitter/receiver/transceiver)
            $smpp->bindTransmitter($systemId, $password);
            
            // 认证成功后发送短信
            $fromAddress = new SmppAddress($from, SMPP::TON_ALPHANUMERIC);
            $toAddress = new SmppAddress($to, SMPP::TON_INTERNATIONAL, SMPP::NPI_E164);
            $smpp->sendSMS($fromAddress, $toAddress, $message);
            
            // 关闭连接
            $smpp->close();
            dd("认证成功,短信发送完成");
        } catch (Exception $e) {
            Log::error("SMPP操作失败: " . $e->getMessage());
            dd("认证或发送失败: " . $e->getMessage());
        }
    }
}

额外排查点

  • 确认SMPP版本:部分服务器要求特定版本(如v3.4),可在bind时指定:$smpp->bindTransmitter($systemId, $password, null, null, null, SMPP::VERSION_3_4);
  • 编码检查:确保systemId和password的编码与服务器要求一致(通常为ASCII)
  • 调试日志:开启setDebug(true)后会输出详细交互日志,可查看原始数据包定位问题
  • 绑定类型与端口:确认服务器端口正确,以及应使用的绑定类型(transmitter/receiver/transceiver)

内容的提问来源于stack exchange,提问作者le prince

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 05:07:46