概述
项目中需要用到发送短信功能,之前没做过这方面,找人咨询了一下,也网上查了查,发现并不是很复杂。目前项目已经完成了,做个记录以备后用。程序中发送短信主要有4种方法:
1、向当地的运营商申请网关,不需要额外的设备,利用对方提供的 API调用程序发送短信,适用于大型的通信公司。稳定,速度快,适合短信量特别大的需求,需要连接到运营商的网络中,不适合内网项目。
2、短信猫发送短信,借助像 GSM MODEM之类的设备(支持AT指令的手机也行),通过数据线连接电脑来发送短信,这种方法比较适用于小公司及个人。不需要联网,速度慢,简单说就是通过程序调用类似手机的设备发短信,价格看发短信卡的套餐了,适合中小项目。
3、互联网短信平台,由互联网上专业做短信收发的网站代发短信数据,对网站依赖性太高,速度,价格都看选择的短信平台了,有些平台速度快,也稳定,不过价格高。不适合内网项目。
4、内网短信平台产品,其实和短信猫没什么区别,就是单独把短信收发功能做成了一个产品,有支持甚至几十张卡同时发的产品,速度也不慢,短信负载都做的很好了,我们公司自己也有一个类似产品,不过比较庞大,安装麻烦,这类产品通常价格也比较贵。
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.dll和rxtxSerial.dll放到jdk目录中,官方的安装说明非常详细了。
rxtxSerial.dll ---> <JAVA_HOME>jrebin
rxtxParallel.dll ---> <JAVA_HOME>jrebin
RXTXcomm.jar只要放到classpath下就行,不用非得放到jrelibext下面
接下来就可以写代码了,代码其实也不复杂:
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下可以通过“设备管理器”来查看。
也可以使用下面代码来检测端口设备:
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内部有个队列,但是如果一旦设备出错短信就丢了,如果多核设备,还要考虑负载均衡问题等等。
最后
以上就是震动蓝天为你收集整理的Java调用SMSLib发送短信详解的全部内容,希望文章能够帮你解决Java调用SMSLib发送短信详解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复