java 短信猫发送短信的方法
http://zghbwjl.blog.163.com/blog/static/12033667220129175158806/
http://www.smscom.cn/sms_javasoft/
用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 短信猫发送短信的方法相关推荐
- Java调用SMSLib用单口短信猫发送短信详解
技术园地 当前位置:短信猫网站主页 > 技术园地 > [转载]Java调用SMSLib用单口短信猫发送短信详解 发布时间:2017/02/09 点击量:620 SMSLib是Apache的 ...
- 超级终端调用短信猫发送短信说明
转载文章:超级终端调用短信猫发送短信说明 短信发送测试 1.短信收发说明命令说明: 1).设置短消息中心 AT+CSCA="+8613800756500"回车(短信中心具体的号码 ...
- wavecom短信猫发送短信失败
http://www.puppeter.cn/?p=106 wavecom短信猫发送短信失败 发表评论 分类:运维工具 | 标签:sms wavecom | 1,048 views 放置在机房用于监控 ...
- asp.Net下短信猫发送短信中的中文乱码解决
现象:用c#编码调用短信猫发送包含中文字符的短信,但收到的总是乱码或问号(?),使用了Default, Unicode-16等多种编码方式仍然无效,而其他非中文字符都可以正常接收. 另外,在超级终端中 ...
- c#实现wavecom短信猫发送长短信
长短信是有规约的,协议头部分如果是0x40以下,则说明是普通短信,如果是0x40以上,则是长短信,然后在短信内容部分,有六个字节分别定义短信唯一标识以及该短信是第几条,所以长短信发送时每条实际为67个 ...
- Wavecom 短信猫 发送短信设置
短信猫设置(命令为独占,当前命令没有返回写入其他命令提示ERROR) AT+CMGF 设置短信格式 AT+CMGF=0 设置短信为PDU格式 AT+CMGF=1 设置短信为text 格式(不能直接发送 ...
- 通过短信猫发送手机短信
wavecom短信猫常用AT命令 一.一般命令 1. AT+CGMI 给出模块厂商的标识. 2. AT+CGMM 获得模块标识.这个命令用来得到支持的频带 (GSM 900,DCS 1800 或PCS ...
- 通过asp.net 短信猫发短信
如今手机已成为大众交流的主要工具.有关手机的程序开发越来越广泛,本节通过典型实例介绍如何利用短信猫发送.接收短信. 1.方案分析 发短信的一种方法是利用短信猫发短信,本例中使用的是生产的串口短信猫. ...
- 短信猫发送GSM 和 CDMA PDU长短信
GSM和CDMA网络制式下发送PDU长短信实例 短信内容: [这是一封长短信,支持中文.长短信在发送的过程中,需要被拆分成多条短短信发送,而每一条短短信的长度最多仅有67个中文字符.这些被拆分的短短信 ...
最新文章
- OpenStack环境搭建(三:Computer与Controller节点的安装及配置)
- java模拟国际象棋游戏_java国际象棋小游戏
- 06-广度优先搜索:图、队列
- jQuery ajax实现
- Bootstrap 警告框插件Alert 的事件
- yum安装好的php路径,yum安装php的路径是什么_后端开发
- 软件工艺师:专业、务实、自豪》一3.3 笔者个人所推崇的定义
- JDK下载以及配置教程
- 黑马python24期课件和代码_黑马Python 24期全套教程
- 实践练习6:查看 OceanBase 执行计划
- 2021年3月30日百度笔试题
- 基于C++的诊所医院管理系统
- 爬虫基础篇之Scrapy抓取京东
- macOS长按键盘重复输入
- 02-StringStringBuilderStringBuffer
- 基于HTML5+CSS3小说阅读网站设计
- 喂,你要多吃点含乳酸菌的食品
- 世界上最神奇的数字是: 142857
- android屏幕适配之点9图片
- 2022世界燕窝展|上海滋补品展|虫草、海参展谈卖货,还是卖品牌?不再简单。
热门文章
- iOS之深入解析Runloop的底层原理
- 【数据结构与算法】之深入解析“二叉搜索树中的插入操作”的求解思路与算法示例
- python下常用OpenCV代码
- 最近面试一些厂的面经整理(阿里,腾讯,字节等)
- Java中集合 练习 计算疯狂值
- 【嵌入式】Libmodbus之TCP模式Slave端程序示例
- 【工业控制】What is a Waveform
- 【Linux】Linux中目录结构说明
- js reduce实现中间件_实现redux中间件-洋葱模型
- python安装方法3.8.2_Linux安装Python3.8.1的教程详解