php语言的cmpp协议应用

1 篇文章 0 订阅

因为公司网站需要移动物联卡的获取短信内容和发送短信功能,本人上网查了一下,发现几乎全是java语言的,只有两个文章是关于cmpp的php开发.而且只有发短信,还有问题.

这里将我开发的程序贴出来.代码也有些冗余,但功能都可以使用了.

我开发的应用接收短信和发送短信在不同的文件

接收短信是通过linux服务器screen来执行php文件获取短信.

发送短信是前端页面填入卡号和内容,传给后台去建立连接发送短信. (cmpp一个账号可以建立10个连接) 

接收短信:  填入公司的接入码什么的,然后使用screen执行下面这个文件就可以了

<?php

class Cmpp {
    // 设置项
    public $host = "";   //服务商ip
    public $port = "17890";           //端口号
    public $Source_Addr = "";           //企业id  企业代码
    public $Shared_secret = '';         //网关登录密码
    public $Dest_Id = "";      //短信接入码 短信端口号
    public $SP_ID = "";
    public $SP_CODE = "";
    public $Service_Id = "";  
    public $deliver;
    private $socket;
    private $Sequence_Id = 1;
    private $bodyData;
    private $AuthenticatorSource;
    public $CMPP_CONNECT = 0x00000001; // 请求连接
    public $CMPP_CONNECT_RESP = 0x80000001; // 请求连接
    public $CMPP_DELIVER = 0x00000005; // 短信下发
    public $CMPP_DELIVER_RESP = 0x80000005; // 下发短信应答
    public $CMPP_ACTIVE_TEST = 0x00000008; // 激活测试
    public $CMPP_ACTIVE_TEST_RESP = 0x80000008; // 激活测试应答
    public $CMPP_SUBMIT = 0x00000004; // 短信发送
    public $CMPP_SUBMIT_RESP = 0x80000004; // 发送短信应答
    public static $msgid = 1;
    public function createSocket(){
        $this->socket =socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
        socket_connect($this->socket,$this->host, $this->port); 
    }
    public function CMPP_CONNECT(){
        date_default_timezone_set('PRC'); 
        $Source_Addr = $this->Source_Addr;
        $Version = 0x30;
        $Timestamp = date('mdHis');
        //echo $Timestamp;
        $AuthenticatorSource = $this->createAS($Timestamp);
        $bodyData = pack("a6a16CN", $Source_Addr, $AuthenticatorSource, $Version, $Timestamp);
        $this->AuthenticatorSource = $AuthenticatorSource;
        $this->send($bodyData, "CMPP_CONNECT"); 
    }
    public function CMPP_CONNECT_RESP(){
        echo "connect success";
        $body = unpack("CStatus/a16AuthenticatorISMG/CVersion", $this->bodyData);
    }
    public function send($bodyData, $Command,$Sequence=0){
        $Command_Id=0x00000001;
        if($Command =="CMPP_CONNECT"){
            $Command_Id = 0x00000001;
        }elseif($Command =="CMPP_DELIVER_RESP"){
            $Command_Id = 0x80000005;
        }elseif($Command =="CMPP_ACTIVE_TEST_RESP"){
            $Command_Id = 0x80000008;
        }elseif($Command =="CMPP_SUBMIT"){
            $Command_Id = 0x00000004;
        }
        $Total_Length = strlen($bodyData) + 12;
        if($Sequence==0){
            if($this->Sequence_Id <10){
                $Sequence_Id = $this->Sequence_Id;
            }else{
                $Sequence_Id =1;
                $this->Sequence_Id=1;
            }
            $this->Sequence_Id = $this->Sequence_Id+1;
        }else{
            $Sequence_Id = $Sequence;
        }
        $headData = pack("NNN", $Total_Length, $Command_Id, $Sequence_Id);
        // 发送消息
        $this->log("send $Command_Id");
        socket_write($this->socket, $headData.$bodyData, $Total_Length);  
        // $this->listen($Sequence_Id);
        $i=1;
        do{
            $this->listen($Sequence_Id);
            //$i = $i-1;
            sleep(15);//等待时间,进行下一次操作
        }while($i>0);
    }
    public function listen($Sequence_Id){
            // 处理头
            $headData = '';
        try {
            echo 1;
            $headData = socket_read($this->socket, 12);
            if($headData===false){
                system("php -f ./smtp465/smtpsenderror.php");
                $this->resets();
            }
        } catch (Exception $e) {
            echo "reset now \n";
            $this->resets();
            return false;
        }
            if(empty($headData)){
                $this->log("0000");
                return;
            }
            $head = unpack("NTotal_Length/NCommand_Id/NSequence_Id", $headData);
            $this->log("get ".($head['Command_Id'] & 0x0fffffff));
            $Sequence_Id = $head['Sequence_Id'];
            // 处理body
            $this->bodyData = socket_read($this->socket,$head['Total_Length'] - 12);
            //var_dump($this->bodyData);
            switch ( $head['Command_Id'] & 0x0fffffff ) {
                case 0x00000001:
                    $this->CMPP_CONNECT_RESP();
                    break;
                case 0x00000005:
                    $this->CMPP_DELIVER($head['Total_Length'],$Sequence_Id);
                    break;
                case 0x80000005:
                    $this->CMPP_DELIVER($head['Total_Length'],$Sequence_Id);
                    break;
                case 0x00000008:
                    $bodyData=pack("C",1);                   //数据联络包返回
                    $this->send($bodyData, "CMPP_ACTIVE_TEST_RESP",$Sequence_Id);
                    break;
                default:
                    $bodyData=pack("C",1);
                    $this->send($bodyData, "CMPP_ACTIVE_TEST_RESP",$Sequence_Id);
                    break;
            }
    }
    public function CMPP_DELIVER($Total_Length,$Sequence_Id){    //Msg_Id直接用N解析不行,N只有4位
        $contentlen = $Total_Length-109;
        $body = unpack("N2Msg_Id/a21Dest_Id/a10Service_Id/CTP_pid/CTP_udhi/CMsg_Fmt/a32Src_terminal_Id/CSrc_terminal_type/CRegistered_Delivery/CMsg_Length/a".$contentlen."Msg_Content/a20LinkID",$this->bodyData);
        var_dump($body);
        if($body['Msg_Length']>0){
            $data = $body['Msg_Content'];
            //$Msg_Id = $body['Msg_Id'];
            $Msg_Id = ($body['Msg_Id1']& 0x0fffffff);
            $Msg_Idfu = $body['Msg_Id2'];
            $msgidz = unpack("N",substr($this->bodyData,0,8));
            $msgidzz = '0000' .$msgidz[1];
            $kahao = $body['Src_terminal_Id'];
            mysql_connect('localhost','','');
            mysql_select_db('');
            mysql_query('set names utf8');
            $data = trim($data);
            $sql1 = "select id from socket_yd where msgid='".$Msg_Id."'";
            $chongfu = mysql_query($sql1);
            $arrs =array();
            while($arr= mysql_fetch_assoc($chongfu) ){
                $arrs[] = $arr;
            }
            if( $arrs==array() || $arrs[0] == null ){
                $sql = "insert into socket_yd set msgid='".$Msg_Id."',kahao='".$kahao."', content='".addslashes($data)."', add_time='".date('Y-m-d H:i:s')."'";
                mysql_query($sql);
            }
            mysql_close();
            //echo $Msg_Id."\n";
            echo $data."\n";
            echo $Msg_Id.'...'.$kahao."\n";
            $this->CMPP_DELIVER_RESP($msgidzz,$Msg_Idfu,$Sequence_Id);
        }
    }
    // N打包只有4位
    public function CMPP_DELIVER_RESP($Msg_Id,$Msg_Idfu,$Sequence_Id){
        $sendda2 = 0x00;
        $bodyData = pack("N", $Msg_Id).pack("N", $Msg_Idfu).pack("N",$sendda2);
        $this->send($bodyData, "CMPP_DELIVER_RESP",$Sequence_Id);
    }
    /**AuthenticatorSource = MD5(Source_Addr+9 字节的0 +shared secret+timestamp) */
    public function createAS($Timestamp){
        $temp = $this->Source_Addr . pack("a9","") . $this->Shared_secret . $Timestamp;
        return md5($temp, true);
    }
    /*** AuthenticatorISMG =MD5(Status + AuthenticatorSource + shared secret) */
    public function cheakAISMG($Status, $AuthenticatorISMG){
        $temp = $Status . $this->AuthenticatorSource . $this->Shared_secret;
        $this->debug($temp.pack("a",""), 1, 1);
        $this->debug($AuthenticatorISMG.pack("a",""), 2, 1);
        if($AuthenticatorISMG != md5($temp, true)){
            $this->throwErr("ISMG can't pass check .", __LINE__);
        }
    }
public function closes(){
        socket_close($this->socket);
    }
    public function resets(){
        socket_close($this->socket);
        $this->createSocket();
        $this->CMPP_CONNECT();
    }
    public function log($data, $line = null){
        if($line){
            $data = $line . " : ".$data;
        }
        file_put_contents("./cmpp.log", print_r($data, true).PHP_EOL, FILE_APPEND);
    }
    public function debug($data, $fileName, $noExit = false){
        file_put_contents("./$fileName.debug", print_r($data, true));
        if(!$noExit) exit;
    }
    public function throwErr($info, $line){
        die("info: $info in line :$line");
    }
   
}

@unlink("./cmpp.log");
$cmpp = new Cmpp;
$cmpp->createSocket();
$cmpp->CMPP_CONNECT();

?>

下面是发送短信:  前端部分就不发了,后端我也是用exec($str, $out, $res);来执行php文件,方便.

后台:

$tomsisdn = $_POST["tomsisdn"];
$contents = $_POST["contents"];
$str = "php -f /var/www/html/CmppSubmit.php {$tomsisdn} {$contents}";
//echo $str."\n";
exec($str, $out, $res);
if($res ==0)
echo $out[1];
//print_r($out);

<?php
class CMPPSubmit{
    // 设置项      
    public $host = "";   //服务商ip
    public $port = "17890";           //短连接端口号   17890长连接端口号
    public $Source_Addr = "";           //企业id  企业代码
    public $Shared_secret = '';         //网关登录密码
    public $Dest_Id = "";      //短信接入码 短信端口号
    public $SP_ID = "";
    public $SP_CODE = "";
    public $Service_Id = "";    //业务代码   这个是业务代码
    public $deliver;
    private $socket;
    private $Sequence_Id = 1;
    private $bodyData;
    private $AuthenticatorSource;
    public $CMPP_CONNECT = 0x00000001; // 请求连接
    public $CMPP_CONNECT_RESP = 0x80000001; // 请求连接
    public $CMPP_SUBMIT = 0x00000004; // 短信发送
    public $CMPP_SUBMIT_RESP = 0x80000004; // 发送短信应答
    public $CMPP_DELIVER = 0x00000005; // 短信下发
    public $CMPP_DELIVER_RESP = 0x80000005; // 下发短信应答
    public $CMPP_ACTIVE_TEST = 0x00000008; // 激活测试
    public $CMPP_ACTIVE_TEST_RESP = 0x80000008; // 激活测试应答
    public $msgid = 1;
    public $tomsisdn = '';
    public $contents = '';
    public function __construct($argv1,$argv2){
        if($argv1){
            $this->tomsisdn = $argv1;
            $this->contents = $argv2; 
        }else{
            $this->log("has no canshu");exit;
        }
    }
    public function createSocket(){
        $this->socket =socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
        if(!$this->socket) {echo "can't creat socket";exit;}
        $result = socket_connect($this->socket,$this->host, $this->port) or die(socket_strerror());
        $this->CMPP_CONNECT();
    }
    public function CMPP_CONNECT(){
        date_default_timezone_set('PRC'); 
        $Source_Addr = $this->Source_Addr;
        $Version = 0x30;
        $Timestamp = date('mdHis');
        //echo $Timestamp;
        $AuthenticatorSource = $this->createAS($Timestamp);
        $bodyData = pack("a6a16CN", $Source_Addr, $AuthenticatorSource, $Version, $Timestamp);
        $this->AuthenticatorSource = $AuthenticatorSource;
        $this->send($bodyData, "CMPP_CONNECT");
        
    }
    public function CMPP_CONNECT_RESP(){
        echo "CMPP_CONNECT_RESP success \n";
        $body = unpack("CStatus/a16AuthenticatorISMG/CVersion", $this->bodyData);
        $this->CMPP_SUBMIT();
    }
    public function send($bodyData, $Command,$Sequence=0){
        $Command_Id=0x00000001;
        if($Command =="CMPP_CONNECT"){     //cmpp连接
            $Command_Id = 0x00000001;
        }elseif($Command =="CMPP_DELIVER_RESP"){     //下发应答
            $Command_Id = 0x80000005;
        }elseif($Command =="CMPP_ACTIVE_TEST_RESP"){    //数据链路应答
            $Command_Id = 0x80000008;
        }elseif($Command =="CMPP_SUBMIT"){        //发送短信
            $Command_Id = 0x00000004;
        }
        $Total_Length = strlen($bodyData) + 12;
        if($Sequence==0){
            if($this->Sequence_Id <10){
                $Sequence_Id = $this->Sequence_Id;
            }else{
                $Sequence_Id =1;
                $this->Sequence_Id=1;
            }
            $this->Sequence_Id = $this->Sequence_Id+1;
        }else{
            $Sequence_Id = $Sequence;
        }
        $headData = pack("NNN", $Total_Length, $Command_Id, $Sequence_Id);
        // 发送消息
        $this->log("send $Command_Id");
        socket_write($this->socket, $headData.$bodyData, $Total_Length);  
        $this->listen($Sequence_Id);
    }
    public function listen($Sequence_Id){
            // 处理头
            $headData = socket_read($this->socket, 12);
            if(empty($headData)){
                $this->log("0000");
                return;
            }
            $head = unpack("NTotal_Length/NCommand_Id/NSequence_Id", $headData);
            $this->log("get ".($head['Command_Id'] & 0x0fffffff));
            $Sequence_Id = $head['Sequence_Id'];
            // 处理body
            $this->bodyData = socket_read($this->socket,$head['Total_Length'] - 12);
            //var_dump($this->bodyData);
            switch ( $head['Command_Id'] & 0x0fffffff ) {
                case 0x00000001:
                    $this->CMPP_CONNECT_RESP();
                    break;
                // case 0x00000005:
                //     $this->CMPP_DELIVER($head['Total_Length'],$Sequence_Id);
                //     break;
                // case 0x80000005:
                //     $this->CMPP_DELIVER($head['Total_Length'],$Sequence_Id);
                //     break;
                case 0x00000008:
                    $bodyData=pack("C",1);                   //数据联络包返回
                    $this->send($bodyData, "CMPP_ACTIVE_TEST_RESP",$Sequence_Id);
                    break;
                case 0x00000004:
                    $this->CMPP_SUBMIT_RESP();
                    break;
                // case 0x80000004:
                //     $this->CMPP_SUBMIT_RESP();
                //     break;
                default:
                    $bodyData=pack("C",1);
                    $this->send($bodyData, "CMPP_ACTIVE_TEST_RESP",$Sequence_Id);
                    break;
            }
    }
    public function CMPP_DELIVER($Total_Length,$Sequence_Id){    //Msg_Id直接用N解析不行
        $contentlen = $Total_Length-109;
        $body = unpack("N2Msg_Id/a21Dest_Id/a10Service_Id/CTP_pid/CTP_udhi/CMsg_Fmt/a32Src_terminal_Id/CSrc_terminal_type/CRegistered_Delivery/CMsg_Length/a".$contentlen."Msg_Content/a20LinkID",$this->bodyData);
        var_dump($body);
        if($body['Msg_Length']>0){
            $data = $body['Msg_Content'];
            //$Msg_Id = $body['Msg_Id'];
            $Msg_Id = ($body['Msg_Id1']& 0x0fffffff);
            $Msg_Idfu = $body['Msg_Id2'];
            $msgidz = unpack("N",substr($this->bodyData,0,8));
            $msgidzz = '0000' .$msgidz[1];
            mysql_connect('localhost','','');
            mysql_select_db('');
            mysql_query('set names utf8');
            $data = trim($data);
            $sql1 = "select id from socket_yd where msgid='".$Msg_Id."'";
            $chongfu = mysql_query($sql1);
            $arrs =array();
            while($arr= mysql_fetch_assoc($chongfu) ){
                $arrs[] = $arr;
            }
            if( $arrs==array() || $arrs[0] == null ){
                $sql = "insert into socket_yd set msgid='".$Msg_Id."', content='".addslashes($data)."', add_time='".date('Y-m-d H:i:s')."'";
                mysql_query($sql);
            }
            mysql_close();
            //echo $Msg_Id."\n";
            echo $data."\n";
            echo $msgidzz."\n";
            echo $Sequence_Id."\n";
            $this->CMPP_DELIVER_RESP($msgidzz,$Msg_Idfu,$Sequence_Id);
        }
    }
    // N打包只有4位 
    public function CMPP_DELIVER_RESP($Msg_Id,$Msg_Idfu,$Sequence_Id){
        $sendda2 = 0x00;
        $bodyData = pack("NNN", $Msg_Id, $Msg_Idfu,$sendda2);
        $this->send($bodyData, "CMPP_DELIVER_RESP",$Sequence_Id);
    }
    public function CMPP_SUBMIT(){
        $Msg_Id = rand(1,100);
        //$bodyData = pack("a8", $Msg_Id);
        $bodyData = pack("N", $Msg_Id).pack("N", "00000000");
        $bodyData .= pack("C", 1).pack("C", 1);
        $bodyData .= pack("C", 0).pack("C", 0);
        $bodyData .= pack("a10", $this->Service_Id);
        $bodyData .= pack("C", 0).pack("a32", "").pack("C", 0).pack("C", 0).pack("C", 0).pack("C", 0).pack("a6", $this->SP_ID).pack("a2", "02").pack("a6", "").pack("a17", "").pack("a17", "").pack("a21", $this->Dest_Id).pack("C", 1);
        $bodyData .= pack("a32", $this->tomsisdn);
        $bodyData .= pack("C", 0);
        $len = strlen($this->contents);
        $bodyData .= pack("C", $len);
        $bodyData .= pack("a".$len, $this->contents);
        $bodyData .= pack("a20", "00000000000000000000");
        //echo '内容长度:包总长度-183='.(strlen($bodyData)-183)."字节\n"; 
        $this->send($bodyData, "CMPP_SUBMIT",$Msg_Id);
    }
    public function CMPP_SUBMIT_RESP(){
        echo "CMPP_SUBMIT_RESP success"."\n";
        $body = unpack("N2Msg_Id/NResult",$this->bodyData);
        print_r($body);
        socket_close($this->socket);
    }
    /**AuthenticatorSource = MD5(Source_Addr+9 字节的0 +shared secret+timestamp) */
    public function createAS($Timestamp){
        $temp = $this->Source_Addr . pack("a9","") . $this->Shared_secret . $Timestamp;
        return md5($temp, true);
    }
    public function log($data, $line = null){
        if($line){
            $data = $line . " : ".$data;
        }
        file_put_contents("./cmpp1.log", print_r($data, true).PHP_EOL, FILE_APPEND);
    }
}
// @unlink("./cmpp1.log");
$cmpp = new CMPPSubmit($argv[1],$argv[2]);
$cmpp->createSocket();
// $cmpp->CMPP_CONNECT();
// $cmpp->CMPP_SUBMIT();
?>

基本就是这样

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
抱歉,我是语言模型AI,无法提供代码。但是,您可以通过以下步骤来编写Java代码来实现CMPP协议的提交短信: 1. 导入Java Socket类库,用于建立TCP/IP连接。 2. 创建与SMSC的TCP连接,建立Socket 3. 根据CMPP协议格式创建Submit消息,包括消息头和消息体。 4. 将Submit消息通过Socket发送到SMSC。 5. 等待SMSC的响应消息,解析响应消息,检查发送结果。 6. 关闭Socket连接。 下面是一个简单的示例代码片段,可以作为参考: ```java import java.io.*; import java.net.*; public class CMPPSubmit { public static void main(String[] args) { String host = "smgw.example.com"; // SMSC主机名或IP地址 int port = 7890; // SMSC端口号 String spId = "your_sp_id"; // SP的企业代码 String spPassword = "your_sp_password"; // SP的密码 String serviceId = "your_service_id"; // 业务代码 String srcId = "your_src_id"; // 发送者号码 String destId = "dest_phone_number"; // 接收者号码 String msgContent = "Hello, world!"; // 短信内容 try { // 创建Socket连接 Socket socket = new Socket(host, port); // 创建输入输出流 InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream(); // 组装Submit消息 CMPPSubmitMsg submitMsg = new CMPPSubmitMsg(); submitMsg.setSpId(spId); submitMsg.setSpPassword(spPassword); submitMsg.setServiceId(serviceId); submitMsg.setSrcId(srcId); submitMsg.setDestId(destId); submitMsg.setMsgContent(msgContent); // 发送Submit消息 byte[] bytes = submitMsg.toBytes(); out.write(bytes); // 等待响应消息 byte[] respBytes = new byte[1024]; in.read(respBytes); CMPPRespMsg respMsg = new CMPPRespMsg(); respMsg.fromBytes(respBytes); // 检查响应消息 if (respMsg.getStatus() == 0) { System.out.println("短信发送成功"); } else { System.out.println("短信发送失败,错误码:" + respMsg.getStatus()); } // 关闭连接 socket.close(); } catch (Exception e) { e.printStackTrace(); } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值