Java调用SMSLib发送短信具体解释

      项目中须要用到发送短信功能。之前没做过这方面。找人咨询了一下。也网上查了查。发现并非非常复杂。

眼下项目已经完毕了。做个记录以备后用。程序中发送短信主要有4种方法:


     1、向当地的运营商申请网关,不须要额外的设备,利用对方提供的 API调用程序发送短信。适用于大型的通信公司。稳定。速度快。适合短信量特别大的需求。须要连接到运营商的网络中。不适合内网项目。
     2、短信猫发送短信,借助像 GSM MODEM之类的设备(支持AT指令的手机也行),通过数据线连接电脑来发送短信。这样的方法比較适用于小公司及个人。不须要联网,速度慢,简单说就是通过程序调用类似手机的设备发短信,价格看发短信卡的套餐了,适合中小项目。
     3、互联网短信平台,由互联网上专业做短信收发的站点代发短信数据,对站点依赖性太高。速度,价格都看选择的短信平台了。有些平台速度快,也稳定。只是价格高。不适合内网项目。
     4、内网短信平台产品。事实上和短信猫没什么差别,就是单独把短信收发功能做成了一个产品,有支持甚至几十张卡同一时候发的产品,速度也不慢,短信负载都做的非常好了。我们公司自己也有一个类似产品。只是比較庞大,安装麻烦,这类产品通常价格也比較贵。


     终于我们选择了使用短信猫发送短信。估计一天1000左右的短信量。不算大,并且内网项目。不能连接外部网络和互联网。
     由于怕后期短信量增大,一张卡每天发送短信太多会被运营商觉得发送垃圾短信封掉,所以開始设备选择了4核的短信猫。能放4张卡,可惜设备驱动不支持。后来又换成了普通的短信猫,串口 GSM的,以下说说java程序怎样和短信猫通信发送短信。

     操作短信猫须要发送AT指令(就是一套控制短信设备的标准运行,详情能够百度一下),由于短信猫是串口设备。Java须要与串口进行通讯,发送 AT指令。
     既然都是标准。通常就有现成的组件。发送指令控制短信猫等功能能够使用SMSLib这个开源组件完毕。SMSLib是Apache的一个开源项目。程序与串口通讯也有非常多组件,SMSLib官网上提供了两种:

     

     JavaComm仅仅支持32位的windows,我们是windows server 2008 64位版本号,仅仅能选择RxTx来与串口通信。终于依赖jar包有4个:

     

     windows和串口通讯还须要依赖操作系统的功能。所以 RxTx还须要将rxtxParallel.dllrxtxSerial.dll放到jdk文件夹中,官方的安装说明很具体了。
     rxtxSerial.dll ---> <JAVA_HOME>\jre\bin
     rxtxParallel.dll ---> <JAVA_HOME>\jre\bin
     RXTXcomm.jar仅仅要放到classpath下即可,不用非得放到jre\lib\ext以下

     

     接下来就能够写代码了,代码事实上也不复杂:
package com.piaohan.sms;

import org.smslib.Message.MessageEncodings;
import org.smslib.OutboundMessage;
import org.smslib.Service;
import org.smslib.modem.SerialModemGateway;

public class SMSDemo {

    public static void main(String args[]) throws Exception {

        // ---------------创建串口设备,假设有多个,就创建多个--------------
        // 1、你自己连接网关的id
        // 2、com口名称,如COM1或/dev/ttyS1(依据实际情况改动)
        // 3、串口波特率。如9600(依据实际情况改动)
        // 4、开发商,如Apple
        // 5、型号,如iphone4s
        SerialModemGateway gateway = new SerialModemGateway("SMS" , "COM3",
                9600, "", "");

        gateway.setInbound( true); // 设置true,表示该网关能够接收短信
        gateway.setOutbound( true); // 设置true,表示该网关能够发送短信

        // -----------------创建发送短信的服务(它是单例的)----------------
        Service service = Service. getInstance();

        // ---------------------- 将设备加到服务中----------------------
        service.addGateway(gateway);

        // ------------------------- 启动服务 -------------------------
        service.startService();

        // ------------------------- 发送短信 -------------------------
        OutboundMessage msg = new OutboundMessage("187xxxxxxxx" , "Hello World");
        msg.setEncoding(MessageEncodings. ENCUCS2);

        service.sendMessage(msg);

        // ------------------------- 关闭服务 -------------------------
        service.stopService();
    }

}
     代码不多,可是第一次弄这个时候搞了好久,碰到的问题不少。主要在于串口配置那。串口名称,波特率不知道。事实上windows下能够通过“设备管理器”来查看。

     

     也能够使用以下代码来检測port设备:

import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

/**
 * CommTest 检測端口
 */
public class ComTone {
    /** 常见端口波特率 */
    public static int bauds[] = { 9600, 19200, 57600, 115200 };

    @SuppressWarnings( "unchecked" )
    public static void main(String[] args) {

        Enumeration<CommPortIdentifier> portList = CommPortIdentifier
                . getPortIdentifiers();

        long st = System. currentTimeMillis();

        System. out.println( "短信设备端口连接測试..." );

        while (portList.hasMoreElements()) {

            CommPortIdentifier portId = (CommPortIdentifier) portList
                    .nextElement();

            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL ) {
                System. out.println( "找到串口:" + portId.getName() + "\t类型:"
                        + getPortTypeName(portId.getPortType()));

                for ( int i = 0; i < bauds. length; i++) {
                    System. out.print( "  Trying at " + bauds [i] + "..." );
                    try {
                        SerialPort serialPort;
                        InputStream inStream;
                        OutputStream outStream;
                        int c;
                        String response;
                        serialPort = (SerialPort) portId.open(
                                "SMSLibCommTester" , 1000);
                        serialPort
                                .setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN );
                        serialPort.setSerialPortParams(bauds [i],
                                SerialPort. DATABITS_8 , SerialPort.STOPBITS_1 ,
                                SerialPort. PARITY_NONE );
                        inStream = serialPort.getInputStream();
                        outStream = serialPort.getOutputStream();
                        serialPort.enableReceiveTimeout(1000);
                        c = inStream.read();
                        while (c != -1)
                            c = inStream.read();
                        outStream.write( 'A');
                        outStream.write( 'T');
                        outStream.write( '\r');
                        try {
                            Thread. sleep(1000);
                        } catch (Exception e) {
                        }
                        response = "";
                        c = inStream.read();
                        while (c != -1) {
                            response += ( char) c;
                            c = inStream.read();
                        }
                        if (response.indexOf( "OK" ) >= 0) {
                            try {
                                System. out.print( "  获取设备信息..." );
                                outStream.write( 'A');
                                outStream.write( 'T');
                                outStream.write( '+');
                                outStream.write( 'C');
                                outStream.write( 'G');
                                outStream.write( 'M');
                                outStream.write( 'M');
                                outStream.write( '\r');
                                response = "";
                                c = inStream.read();
                                while (c != -1) {
                                    response += ( char) c;
                                    c = inStream.read();
                                }
                                System. out.println( "  发现设备: "
                                        + response.replaceAll("\\s+OK\\s+" , "")
                                                .replaceAll("\n" , "")
                                                .replaceAll("\r" , ""));
                            } catch (Exception e) {
                                System. out.println( "  没有发现设备!" );
                            }
                        } else
                            System. out.println( "  没有发现设备!" );
                        serialPort.close();
                    } catch (Exception e) {
                        System. out.println( "  没有发现设备!" );
                    }
                }
                System. out.println( "找到串口: " + portId.getName());
            }
        }
        long et = System. currentTimeMillis();
        long time = et - st;
        System. out.println( "系统的试执行时间:" + time + "毫秒" );
    }

    private static String getPortTypeName( int portType) {
        switch (portType) {
        case CommPortIdentifier. PORT_I2C :
            return "I2C" ;
        case CommPortIdentifier. PORT_PARALLEL :
            return "Parallel" ;
        case CommPortIdentifier. PORT_RAW :
            return "Raw" ;
        case CommPortIdentifier. PORT_RS485 :
            return "RS485" ;
        case CommPortIdentifier. PORT_SERIAL :
            return "Serial" ;
        default:
            return "unknown type" ;
        }
    }
}
     执行结果例如以下:

     

     最后,有个要注意的地方,上面的代码所有是測试代码,假设真要放到项目中使用,最好自己维护一个短信发送队列。由于发1条短信大约5s左右,太多的话尽管smslib内部有个队列,可是假设一旦设备出错短信就丢了。假设多核设备。还要考虑负载均衡问题等等。
posted @ 2017-06-15 21:13  jzdwajue  阅读(966)  评论(0编辑  收藏  举报