用java实现短信收发的功能,目前一般项目中短信群发功能的实现方法大致有下面三种:

·                 1、 向运行商申请短信网关,不需要额外的设备,利用运行商提供的API调用程序发送短信,适用于大型的通信公司。

·                 2、 借助像GSM MODEM之类的设备(支持AT指令的手机也行),通过数据线连接电脑来发送短信,这种方法比较适用于小公司及个人。要实现这种方式必须理解串口通信、AT指令、短信编码、解码。

·                 3、 借助第三方运行的网站实现,由网站代发短信数据,这种方法对网站依赖性太高,对网络的要求也比较高。

鉴于项目的情况和多方考虑,同时又找到了一个开源的SMSLib项目的支持,比较倾向于第二种方法,SMSLib的出现就不需要我们自己去写底层的AT指令,这样就可以直接通过调用SMSLib的API来实现通过GSM modem来收发送短信了。

SMSLib官方网站:http://smslib.org/,使用SMSLib的一些基本要点:

·                 SUN JDK 1.6 or newer. (Java环境)

·                 Java CommunicationsLibrary. (Java串口通信)

·                 Apache ANT for building thesources. (编译源码时需要的)

·                 Apache log4j. (日志工具)

·                 Apache Jakarta Commons -NET. (网络操作相关的)

·                 JSMPP Library (SMPP协议时需要的)

有关Java串口通信需要补充说明:

·                 window系统可以用SUN Java Comm v2. (该版本好像也支持solaris)

其下载地址:http://smslib.googlecode.com/files/javacomm20-win32.zip

·                 其他操作系统(比如:Linux, Unix, BSD,等等),你可以选择 Java Comm v3 或者是RxTx。

Java Comm v3下载地址:http://java.sun.com/products/javacomm/(需要注册); 
         RxTx官网:http://users.frii.com/jarvi/rxtx/index.html or http://rxtx.qbang.org/wiki/index.php/Main_Page

附件提供相关下载:

·                 java串口通信v2:javacomm20-win32.zip

·                 smslib-3.5.1.jar

·                 短信modem驱动:PL2303_Prolific_DriverInstaller_v130.zip

本次测试的环境是window,GSM modem是wavecom,所以这次主要描述window环境下简单的实现过程: 
【一】、配置相应的环境 
     首先解压下载的Java Comm v2文件javacomm20-win32.zip,具体配置步骤如下:

·                 把文件:comm.jarcopy 到目录:JDKDIR/jre/lib/ext/,当然这一步也可以不要这样做,你只需把comm.jar copy到所要运行的项目对应的lib/下既可

·                 把文件:javax.comm.propertiescopy 到目录:JDKDIR/jre/lib/

·                 把DLL文件:win32com.dll(windows) copy 到目录:JDKDIR/jre/bin/

如果存在JRE目录, 最好安装上面步骤把文件copy到JREDIR相应的目录下

测试串口端口程序: 
Test .java

Java代码

package test;

import java.util.Enumeration;

import javax.comm.CommDriver;

import javax.comm.CommPortIdentifier;

import javax.comm.SerialPort;

public class Test {

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

       // 人工加载驱动  

       // MainTest.driverInit();  

  Test.getCommPortList();  

       // 人工加载驱动获取端口列表  

       // TestGetPortList.getPortByDriver();  

   }  

   /** 

    * 手工加载驱动<br> 

    * 正常情况下程序会自动加载驱动,故通常不需要人工加载<br> 

    * 每重复加载一次,会把端口重复注册,CommPortIdentifier.getPortIdentifiers()获取的端口就会重复 

    */  

   public static void driverManualInit() {  

       String driverName = "com.sun.comm.Win32Driver";  

       String libname = "win32com";  

       CommDriver commDriver = null;  

       try {  

           System.loadLibrary("win32com");  

           System.out.println(libname + " Library Loaded");  

           commDriver = (javax.comm.CommDriver) Class.forName(driverName)  

                   .newInstance();  

           commDriver.initialize();  

           System.out.println("comm Driver Initialized");  

       } catch (Exception e) {  

           System.err.println(e);  

       }  

   }  

   /** 

    * 获取端口列表 

    */  

   public static void getCommPortList() {  

       CommPortIdentifier portId;  

       Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();  

       while (portEnum.hasMoreElements()) {  

           portId = (CommPortIdentifier) portEnum.nextElement();  

           if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {  

               System.out.println("串口: name-" + portId.getName()  

                       + " 是否占用-" + portId.isCurrentlyOwned());  

           } else {  

               System.out.println("并口: name-" + portId.getName()  

                       + " 是否占用-" + portId.isCurrentlyOwned());  

           }  

       }  

       System.out.println("-------------------------------------");  

   }  

   /** 

    *  

    */  

   public static void getPortByDriver() {  

       String driverName = "com.sun.comm.Win32Driver";  

       String libname = "win32com";  

       CommDriver commDriver = null;  

       try {  

           System.loadLibrary("win32com");  

           System.out.println(libname + " Library Loaded");  

           commDriver = (CommDriver) Class.forName(driverName).newInstance();  

           commDriver.initialize();  

           System.out.println("comm Driver Initialized");  

       } catch (Exception e) {  

           System.err.println(e);  

       }  

       SerialPort sPort = null;  

       try {  

           sPort = (SerialPort) commDriver.getCommPort("COM24",  

                   CommPortIdentifier.PORT_SERIAL);  

           System.out.println("find CommPort:" + sPort.toString());  

       } catch (Exception e) {  

           System.out.println(e.getMessage());  

       }  

   }  

}
 

本机运行结果:

引用

串口: name-COM10 是否占用-false 
串口: name-COM21 是否占用-false 
串口: name-COM23 是否占用-false 
串口: name-COM20 是否占用-false 
串口: name-COM22 是否占用-false 
串口: name-COM24 是否占用-false 
串口: name-COM9 是否占用-false 
串口: name-COM19 是否占用-false 
串口: name-COM3 是否占用-false 
串口: name-COM8 是否占用-false 
串口: name-COM98 是否占用-false 
串口: name-COM99 是否占用-false 
串口: name-COM4 是否占用-false 
串口: name-COM5 是否占用-false 
串口: name-COM6 是否占用-false 
并口: name-LPT1 是否占用-false 
并口: name-LPT2 是否占用-false 
-------------------------------------

【三】、检查串口设备信息: 
TestCommPort .java

Java代码

package test;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.Enumeration;

import javax.comm.CommPortIdentifier;

import javax.comm.SerialPort;

public class TestCommPort {

    static CommPortIdentifier portId;  

    static Enumeration portList;  

    static int bauds[] = { 9600, 19200, 57600, 115200 };  

    /** 

     * @param args 

     */  

    public static void main(String[] args) {  

        portList = CommPortIdentifier.getPortIdentifiers();  

        System.out.println("GSM Modem 串行端口连接测试开始...");  

        String portName = "COM4";  

        while (portList.hasMoreElements()) {  

            portId = (CommPortIdentifier) portList.nextElement();  

            if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL  

                    && portName.equals(portId.getName())) {  

                System.out.println("找到串口: " + portId.getName());  

                for (int i = 0; i < bauds.length; i++) {  

                    System.out.print("  Trying at " + bauds[i] + "...");  

                    try {  

                        SerialPort serialPort;  

                        InputStream inStream;  

                        OutputStream outStream;  

                        int c;  

                        StringBuffer response = new StringBuffer();  

                        serialPort = (SerialPort) portId.open(  

                                "SMSLibCommTester", 1971);  

                        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) {  

                        }  

                        c = inStream.read();  

                        while (c != -1) {  

                            response.append((char) c);  

                            c = inStream.read();  

                        }  

                        if (response.indexOf("OK") >= 0) {  

                            System.out.print("  正在检测设备:");  

                            try {  

                                outStream.write('A');  

                                outStream.write('T');  

                                outStream.write('+');  

                                outStream.write('C');  

                                outStream.write('G');  

                                outStream.write('M');  

                                outStream.write('M');  

                                outStream.write('\r');  

                                response = new StringBuffer();  

                                c = inStream.read();  

                                while (c != -1) {  

                                    response.append((char) c);  

                                    c = inStream.read();  

                                }  

                                System.out.println("  发现设备: "  

                                        + response.toString().replaceAll(  

                                                "(\\s+OK\\s+)|[\n\r]", ""));  

                            } catch (Exception e) {  

                                System.out.println("  检测设备失败,获取设备信息异常:"  

                                        + e.getMessage());  

                            }  

                        } else {  

                            System.out.println("  检测设备失败,沒有接收到响应结果!");  

                        }  

                        serialPort.close();  

                    } catch (Exception e) {  

                        System.out.println("  检测设备失败,发生异常:" + e.getMessage());  

                    }  

                }  

            }  

        }  

    }  

}  
 

运行结果如下:

引用

GSM Modem 串行端口连接测试开始... 
找到串口: COM24 
  Trying at 9600...  正在检测设备: 发现设备: AT+CGMM MULTIBAND  900E 1800 
  Trying at 19200...  发现设备失败,沒有接收到响应结果! 
  Trying at 57600...  发现设备失败,沒有接收到响应结果! 
  Trying at 115200...  发现设备失败,沒有接收到响应结果!

【四】、测试收发短信:

Java代码

package test;

import java.util.ArrayList;

import java.util.LinkedList;

import java.util.List;

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.smslib.AGateway;

import org.smslib.AGateway.Protocols;

import org.smslib.GatewayException;

import org.smslib.InboundMessage;

import org.smslib.Message.MessageEncodings;

import org.smslib.OutboundMessage;

import org.smslib.Service;

import org.smslib.modem.SerialModemGateway;

public class SendSmsHandler {  

    private static final Logger logger = Logger.getLogger(SendSmsHandler.class);  

    private Service smsService;  

    /** 

     * 发送短信的类

     */  

    public SendSmsHandler() {  

        smsService = Service.getInstance();  //获得服务实例  单例模式的

        List<AGateway> agatewayList = new ArrayList<AGateway>();  

        String portName = "COM4";//"/dev/ttyUSB0";// COM24  //使用的端口号

        SerialModemGateway gateway = new SerialModemGateway(  

                "modem." + portName, portName, 9600, "wavecom", "PL2303");  //通过端口号频率名称等内容获得设备实例

        gateway.setInbound(true);  

        gateway.setOutbound(true);  

        gateway.setProtocol(Protocols.PDU);  //发送凡是PDU

        gateway.setSimPin("0000");  

        agatewayList.add(gateway);  //放到队列中,群发可以放多条就可以了

        try {  

            for (AGateway gatewayTmp : agatewayList) {  

                smsService.addGateway(gatewayTmp);  

            }  

        } catch (GatewayException ex) {  

            logger.error(ex.getMessage());  

        }  

    }  

    /** 

     *  启动发送短信的服务

     */  

    public void start() {  

        logger.info("SMS service start.....");  

        try {  

            smsService.startService();  

        } catch (Exception ex) {  

            logger.error("SMS service start error:", ex);  

        }  

    }  

    /** 

     *  停止发送短信服务

     */  

    public void destroy() {  

        try {  

            smsService.stopService();  //停止服务

        } catch (Exception ex) {  

            logger.error("SMS service stop error:", ex);  

        }  

        logger.info("SMS service stop");  

    }  

    /** 

     * send SMS 

     * 发送短信的方法

     * @param msg 发送的内容

     * @return Boolean 返回是否发送成功

     */  

    public Boolean sendSMS(OutboundMessage msg) {  

        try {  

            msg.setEncoding(MessageEncodings.ENCUCS2);  //设置编码

            return smsService.sendMessage(msg);  //发送短信并返回结果

        } catch (Exception e) {  

            logger.error("send error:", e);  

        }  

        return false;  

    }  

//服务是否已经启动

    private boolean isStarted() {  

        if (smsService.getServiceStatus() == Service.ServiceStatus.STARTED) {  //服务的状态是否是启动

            for (AGateway gateway : smsService.getGateways()) {  

                if (gateway.getStatus() == AGateway.GatewayStatuses.STARTED) {  

                    return true;  

                }  

            }  

        }  

        return false;  

    }  

    /** 

     * read SMS 去读接收到的短信信息

     * @return List 

     */  

    public List<InboundMessage> readSMS() {  

        List<InboundMessage> msgList = new LinkedList<InboundMessage>();  

        if (!isStarted()) {  

            return msgList;  

        }  

        try {  

            this.smsService.readMessages(msgList,  

                    InboundMessage.MessageClasses.ALL);  

            logger.info("read SMS size: " + msgList.size());  

        } catch (Exception e) {  

            logger.error("read error:", e);  

        }  

        return msgList;  

    }  

    /** 

     * @param args 测试类

     */  

    public static void main(String[] args) {  

        Logger.getRootLogger().setLevel(Level.INFO);  

        OutboundMessage outMsg = new OutboundMessage("189*****", "信息测试");  //绑定接收电话号码和发送的消息

        SendSmsHandler smsHandler = new SendSmsHandler();  

        smsHandler.start();  //启动

        //发送短信  

        smsHandler.sendSMS(outMsg);  

        //读取短信  

        List<InboundMessage> readList = smsHandler.readSMS();  

        for (InboundMessage in : readList) {  

            System.out.println("发信人:" + in.getOriginator() + " 短信内容:"  

                    + in.getText());  

        }  

        smsHandler.destroy();  //停止服务

        System.out.println("-----------");  

    }  

}
 

发送短信亲测,手机能正常接收显示。读取设备的短信程序运行结果结果如下:

引用

INFO
- Service.listSystemInformation(113) | SMSLib: A Java API library
forsending and receiving SMS via a GSM modem or other supported
gateways. 
This software is distributed under the terms of the Apache v2.0 License. 
Web Site: http://smslib.org 
INFO - Service.listSystemInformation(114) | Version: 3.5.1 
INFO - Service.listSystemInformation(115) | JRE Version: 1.6.0_18 
INFO - Service.listSystemInformation(116) | JRE Impl Version: 16.0-b13 
INFO - Service.listSystemInformation(117) | O/S: Windows Vista / x86 /6.0 
INFO - SmsHandler.start(55) | SMS service start..... 
INFO - DefaultQueueManager.init(92) | Queue directory not defined. Queuedmessages will not be saved to filesystem. 
INFO - ModemGateway.startGateway(188) | GTW: modem.COM24: Starting gateway,using Generic AT Handler. 
INFO - SerialModemDriver.connectPort(68) | GTW: modem.COM24: Opening: COM24@9600 
INFO - AModemDriver.waitForNetworkRegistration(459) | GTW: modem.COM24: GSM:Registered to foreign network (roaming). 
INFO - AModemDriver.connect(175) | GTW: modem.COM24: MEM: Storage LocationsFound: SMBM 
INFO - CNMIDetector.getBestMatch(142) | CNMI: No best match, returning: 1 
INFO - ModemGateway.startGateway(191) | GTW: modem.COM24: Gatewaystarted. 
INFO - SmsHandler.readSMS(113) | read SMS size: 1 
发信人:8618918001030 短信内容:hello 回复测试 
INFO - ModemGateway.stopGateway(197) | GTW: modem.COM24: Stoppinggateway... 
INFO - SerialModemDriver.disconnectPort(120) | GTW: modem.COM24: Closing: COM24@9600 
INFO - ModemGateway.stopGateway(201) | GTW: modem.COM24: Gateway stopped. 
INFO - SmsHandler.destroy(72) | SMS service stop 
-----------

java 短信猫发送短信的方法的更多相关文章

  1. 使用短信猫发送短信java代码

    短信猫简单配置:https://www.cnblogs.com/Big-Boss/p/9699880.html 发送短信: package utils; import org.smslib.AGate ...

  2. Linux系统中调用短信猫发送短信(笔记)

    1, 拷贝底层串口依赖的librxtxSerial.so到JDK安装路径cp librxtxSerial.so /usr/java/{0}/jre/lib/{1} # {0}: JDK的基础目录,例如 ...

  3. 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案

    方案特点: 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案,简化软件开发流程,减少各应用系统相同模块的重复开发工作,提高系统稳定性和可靠性. 基于HTTP协议的开发接口 使用特点在网页 ...

  4. .NET 微信开放平台接口(接收短信、发送短信)

    .NET 微信开放平台接口(接收短信.发送短信) 前两天做个项目用到了微信api功能.项目完成后经过整理封装如下微信操作类. 以下功能的实现需要开发者已有微信的公众平台账号,并且开发模式已开启.接口配 ...

  5. 移动MAS短信平台发送短信

    MAS短信平台发送短信分为两种方式 参考文档下载 一.sdk调用 using mas.ecloud.sdkclient; using System; namespace 短信发送 { class Pr ...

  6. 使用短信猫读取短信java代码

    短信猫简单配置:https://www.cnblogs.com/Big-Boss/p/9699880.html 测试发送短信代码:https://www.cnblogs.com/Big-Boss/p/ ...

  7. java中用中国网建提供的SMS短信平台发送短信

    接下来的项目需求中提到需要短信发送功能,以前没有做过,因此便在网上搜了一下.大体上说的都是有三种方法,分别是sina提供的webservice接口.短信mao和中国网建提供的SMS短信平台. 这三种方 ...

  8. JAVA实现多线程处理批量发送短信、APP推送

    /** * 推送消息 APP.短信 * @param message * @throws Exception */ public void sendMsg(Message message) throw ...

  9. 阿里云短信服务发送短信验证码(JAVA开发此功能)

    开发此功能需注册阿里云账号,并开通短信服务(免费开通) 充值后,不会影响业务的正常使用!(因为发送验证类短信:1-10万范围的短信是0.045元/条).开发测试使用,充2块钱测试足够了 可参考阿里云官 ...

随机推荐

  1. Maven运行报错:-Dmaven.multiModuleProjectDirectory system propery is not set.

    eclipse中使用maven插件的时候,运行run as maven build的时候报错 -Dmaven.multiModuleProjectDirectory system propery is ...

  2. Python中sys.argv的用法

    sys.argv是获取运行python文件的时候命令行参数 下面的代码文件是a.py,当我不用IDE工具,只用命令行窗口运行的时候,进入文件所在目录,输入:python a.py 输出结果如下 imp ...

  3. 四丶人生苦短,我用python【第四篇】

    1 基本数据类型 数字    int 字符串   str 布尔值   bool 列表       list 元组       tuple 字典       dict >>>type( ...

  4. bootshiro---开源的后台管理框架--基于springboot2+ shiro+jwt的真正rest api资源无状态认证权限管理框架,开发人员无需关注权限问题,后端开发完api,前端页面配置即可

    https://gitee.com/tomsun28/bootshiro

  5. HDU 5483 Nux Walpurgis

    Nux Walpurgis Time Limit: 8000ms Memory Limit: 131072KB This problem will be judged on HDU. Original ...

  6. TOJ 2710: 过河 路径压缩

    2710: 过河  Time Limit(Common/Java):1000MS/10000MS     Memory Limit:65536KByteTotal Submit: 32         ...

  7. ubuntu系统下如何禁用笔记本触摸板

    命令行方式,得每次用终端输入命令行设置,不方便. sudo rmmod psmouse          # 用来禁用触摸板 sudo modprobe psmouse     # 用来启用触摸板 想 ...

  8. UOJ 34 多项式乘法 ——NTT

    [题目分析] 快速数论变换的模板题目. 与fft的方法类似,只是把复数域中的具有循环性质的单位复数根换成了模意义下的原根. 然后和fft一样写就好了,没有精度误差,但是跑起来比较慢. 这破题目改了好长 ...

  9. TeraTerm设定(窗体大小,字体字号)保存为默认值

    Tera Term是一款很好的SSH工具,大家经常遇到一个头疼的问题,每次打开的时候,都要自己重新设置一遍Font. 介绍一下把自己喜欢的字体,设置好后,保存到默认配置中的方法. 设置窗体大小: 设置 ...

  10. 转载 :sql server 2005 无法删除数据库 "#Test",因为该数据库当前正在使用

    无法删除数据库 "#Test",因为该数据库当前正在使用 --查询分析器中执行下面的语句就行了. use master go declare @dbname sysname set ...