Java应用短信猫
首先确定短信猫正常连接到主机,并安装SIM卡。
先用超级终端测试短息猫能不能用。
安装minicom:
#sudo apt-get install minicom
安装完成后,执行
#sudo minicom -s

使用光标上下选择:Serial port setup,如下图

按A,设置端口号,COM1对应/dev/ttyS0,
按E,修改波特率、奇偶校验等,我的短信猫波特率用的是默认,
按F,将Hardware Flow Control变为NO,
按Enter键,返回,
选择Save setup as dfl,即作为默认配置,
选择Exit,进入到Minicom:

输入at,按Enter,若打印出ok,则正常。
输入at+cmgf=1,设置短信格式,1是文本格式,0是PDF格式,
输入at+cmgs=xxxxx,接收手机号码,Enter,接着输入内容,按Ctrl+Z,等待,
界面打印OK,手机接收短信。
超级终端成功,接下来调试Java代码,我使用的jar包是jssc-2.8.0.jar
下面是代码:
package com.sendSMS;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
import jssc.SerialPortList;
public class Sender {
private String msgCenterPhone;
private String portName;
private int baud;
private int parity;
private int stop;
private int data;
private int gsmType;
private SerialPort serialPort;
/** AT+CMGS= */
public final static byte[] SMS_STRUCTOR = {
0x41, 0x54, 0x2B, 0x43, 0x4D, 0x47, 0x53, 0x3D};
/** AT+CMGF=0 */
public final static byte[] SMS_PDU_HEADER = {
0x41, 0x54, 0x2B, 0x43, 0x4D, 0x47, 0x46, 0x3D, 0x30};
public final static byte[] SMS_HEADER_START = {
0x41, 0x54, 0x2B, 0x43, 0x4D, 0x47, 0x53, 0x3D};
public final static byte[] SMS_HEADER_END = {
0x0D};
public final static byte[] SMS_CONTENT_END = {
0x1A};
public void setCenterPhone(String phoneNumber) {
this.msgCenterPhone = phoneNumber;
}
public void setSerialPort(String portName) {
this.portName = portName;
}
public void setParams(int baudRate, int parity, int stop, int data) {
this.baud = baudRate;
this.parity = parity;
this.stop = stop;
this.data = data;
}
public void setGSMType(int gsmType) {
this.gsmType = gsmType;
}
public Sender() {
//msgCenterPhone = msgCenterPhone.trim();
portName = "COM10";
baud = 115200;
parity = 0;
stop = 1;
data = 8;
gsmType = 2;
}
public Sender(String phoneNo, String portName, int gsmType) {
msgCenterPhone = phoneNo;
this.portName = portName;
baud = 115200;
parity = 0;
stop = 1;
data = 8;
this.gsmType = gsmType;
}
/**
* 确认发送格式并发送短信,将长短信分为N条正常短信
* @param mobileSendAlarmInfo
* @return 1:发送成功;-1:发送失败
*/
public int sendSMS(String destPhone, String content){
/**
* 发送成功标志
*/
int succeedFlag = 0;
serialPort = new SerialPort(this.portName);
try {
System.out.println("Port opened:" + serialPort.openPort());
System.out.println("Params setted:" + serialPort.setParams(115200, 8 , 1, 0));
System.out.println("Send PDU Header" + serialPort.writeBytes(SMS_PDU_HEADER));
System.out.println("Send Header End" + serialPort.writeBytes(SMS_HEADER_END));
int timeout = 0;
while (true) {
Thread.sleep(100);
byte[] b = new byte[21];
b = serialPort.readBytes();
if (timeout > 50) {
System.out.println("Time Out");
serialPort.closePort();
return succeedFlag = -1;
}
if (b == null) {
timeout++;
continue;
}
String s = new String(b);
if (s.indexOf("OK") != -1) { //'OK'
System.out.println("Set PDU Successful!");
break;
}
}
int[] tpduLength = new int[1];
String pack = packStrMessage(destPhone, content, msgCenterPhone,
tpduLength);
System.out.println("Send Header Start" + serialPort.writeBytes(SMS_HEADER_START));
String strLength = (tpduLength[0] < 100 ?
("0" + Integer.toString(tpduLength[0])) :
Integer.toString(tpduLength[0]));
System.out.println("Send Header Length"+ serialPort.writeBytes(strLength.getBytes()));
System.out.println("Send Header End" + serialPort.writeBytes(SMS_HEADER_END));
Thread.sleep(100);
timeout = 0;
while (true) {
Thread.sleep(100);
byte[] b = new byte[21];
b = serialPort.readBytes(); if (timeout > 50) {
System.out.println("Time Out");
serialPort.closePort();
return succeedFlag = -1;
}
if (b == null) {
timeout++;
continue;
}
String s = new String(b);
if (s.indexOf('>') != -1) { //'>'
System.out.println("Title Successful!");
break;
}
if (s.indexOf("ERROR") != -1) { //'R'
System.out.println("Error");
serialPort.closePort();
return succeedFlag = -1;
}
}
System.out.println("Send Content: " + serialPort.writeBytes(pack.getBytes()));
System.out.println("Send Contend End: " + serialPort.writeBytes(SMS_CONTENT_END));
System.out.println("Send Header End: " + serialPort.writeBytes(SMS_HEADER_END));
timeout = 0;
while (true) {
Thread.sleep(100);
byte[] b = new byte[21];
b = serialPort.readBytes();
if (timeout > 50) {
System.out.println("Time Out");
serialPort.closePort();
return succeedFlag = -1;
}
if (b == null) {
timeout++;
continue;
}
String s = new String(b);
System.out.println(s);
//System.exit(0);
if (s.indexOf("OK") != -1) { //'>'
System.out.println("Content Successful!");
serialPort.closePort();
return succeedFlag = 1;
}
if (s.indexOf("ERROR") != -1) { //'R'
System.out.println("Error");
serialPort.closePort();
return succeedFlag = -1;
}
}
} catch (SerialPortException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return succeedFlag;
}
private String packStrMessage(String destPhone, String content,
String centerPhone, int[] tpduLength) {
if (destPhone == null || content == null || centerPhone == null)
return "";
//encode the SCA
byte[] sca = new byte[3];
sca[0] = (byte) (0x00);
sca[1] = (byte) 0x11;
sca[2] = (byte) 0x00;
//encode TPDU
if (!destPhone.startsWith("86")) //add china code 86 to dest phone. 81 为日本的代码
destPhone = "86" + destPhone;
int length;
int destLength = length = destPhone.length();
if (length % 2 != 0) { //if the dest code is odd , then add 'F'
destPhone += "F";
length++;
}
//content += new String( new char[]{ 0x00 } );
char[] ccontent = content.toCharArray();
int contentLength = ccontent.length;
/* Data Length
* Dest Phone(encoding) | Data(encoding)
* _________|__________ | _____|________
* The tpdu' sample byte 11 00 0D 91 68 31 19 01 28 14 F1 00 00 00 05 D4 E2 94 0A 02
* | | | | | | |
* | | | TON/NPI | | VP Validity Period
* | | Dest Phone Length(Number) | DCS Data Coding Scheme(00-ASCII , 08-UCS2)
* | MR Message Reference PID Protocol ID
* 8 Bits MTI,RD,VPF,SRR,UDHI,RP,MMS,SRI
* so 4 + phoneLength / 2 + 3 + 1 + contenLength is the tpdu length
*/
byte[] tpdu = new byte[2 + length / 2 + 3 + 1 + contentLength * 2];
int index = 0;
tpdu[index++] = (byte) destLength;
tpdu[index++] = (byte) 0x91;
for (int i = 0; i < length; i += 2) {
tpdu[index++] = swap(destPhone.substring(i, i + 2), 16);
}
tpdu[index++] = 0x00;
tpdu[index++] = 0x08; //UCS2
tpdu[index++] = (byte) 0xA7;
tpdu[index++] = (byte) (contentLength * 2);
for (int i = 0; i < contentLength; i++) {
if (i < ccontent.length) {
tpdu[index++] = (byte) (ccontent[i] >> 8);
tpdu[index++] = (byte) (ccontent[i] & 0x00FF);
} else {
tpdu[index++] = (byte) (0xFF);
tpdu[index++] = (byte) (0xFF);
}
}
//copy sca and tpdu to ret
int scaLength = sca.length;
tpduLength[0] = tpdu.length + 2;
byte[] ret = new byte[scaLength + tpdu.length];
System.arraycopy(sca, 0, ret, 0, scaLength);
System.arraycopy(tpdu, 0, ret, scaLength, tpdu.length);
String r = new String();
for (int i = 0; i < ret.length; i++) {
String s = Integer.toHexString( (char) ret[i] & 0x00ff);
if (s.length() == 1)
s = "0" + s;
r += s;
}
//System.out.println( r );
return r;
}
//swap the string and parse it as specail radix byte,just same binary code.
//note: the s must has two length string.
//eg. swap( "12" , 16 ) will return byte 33
//eg. swap( "68" , 16 ) will return byte -122
public static byte swap(String s, int radix) {
byte b1 = Byte.parseByte(s.substring(0, 1), radix);
byte b2 = Byte.parseByte(s.substring(1, 2), radix);
return (byte) (b2 * radix + b1);
}
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("The SMS Properties:\n");
sb.append("\nSerial Port=" + serialPort);
sb.append("\nBaud=" + baud);
sb.append("\nData Bits=" + data);
sb.append("\nStop Bit=" + stop);
sb.append("\nParity=" + parity);
sb.append("\nSMS Center Phone=" + msgCenterPhone);
return sb.toString();
}
public static void main(String[] args) {
Sender sender = new Sender("13800210500", "/dev/ttyS0", 2);//SIM卡所在地短信中心号码、端口号、SIM卡类型默认2即可
int code = sender.sendSMS("xxxxxxxxxxx", "Just for a test");//接收号码、内容
System.out.println(code);
}
}
编译,还是不行,看下log,好吧,是权限问题,接下来在超级终端中运行:
#sudo chmod 777 /dev/ttyS0
再次编译,手机接到短信了,OK。
在Windows中把端口号换成"COM1"就行了。
Java应用短信猫的更多相关文章
- 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案
方案特点: 在网页程序或Java程序中调用接口实现短信猫收发短信的解决方案,简化软件开发流程,减少各应用系统相同模块的重复开发工作,提高系统稳定性和可靠性. 基于HTTP协议的开发接口 使用特点在网页 ...
- 使用短信猫读取短信java代码
短信猫简单配置:https://www.cnblogs.com/Big-Boss/p/9699880.html 测试发送短信代码:https://www.cnblogs.com/Big-Boss/p/ ...
- java 短信猫发送短信的方法
用java实现短信收发的功能,目前一般项目中短信群发功能的实现方法大致有下面三种: · 1. 向运行商申请短信网关,不需要额外的设备,利用运行商提供的API调用程序发送 ...
- 使用短信猫发送短信java代码
短信猫简单配置:https://www.cnblogs.com/Big-Boss/p/9699880.html 发送短信: package utils; import org.smslib.AGate ...
- Linux系统中调用短信猫发送短信(笔记)
1, 拷贝底层串口依赖的librxtxSerial.so到JDK安装路径cp librxtxSerial.so /usr/java/{0}/jre/lib/{1} # {0}: JDK的基础目录,例如 ...
- 基于Socket客户端局域网或广域网内共享同一短信猫收发短信的开发解决方案
可使同一网络(局域网或广域网)内众多客户端,共享一个短信猫设备短信服务器进行短信收发,短信服务器具备对客户端的管理功能. 下面是某市建设银行采用本短信二次开发平台时实施的系统方案图: 在该方案中,考虑 ...
- 短信猫 TIdTCPServer TIdTCPClient
短信猫 服务端: IdTCPServer1: TIdTCPServer; IdAntiFreeze1: TIdAntiFreeze; unit UnitSever; interface uses Wi ...
- C# 短信猫(SMS cat) 操作源码开发经验
我曾经开发的某项目需要使用短信猫模块,要求使用C#编程操作.能独立使用的动态链接库之一就是网上流传的sms.dll,但它的功能较少,不能满足需求,鉴于一时找不到合适的完整代码,我深入研究了短信协议,借 ...
- wavecom短信猫常用AT命令
wavecom短信猫常用AT命令 一.一般命令 1. AT+CGMI 给出模块厂商的标识. 2. AT+CGMM 获得模块标识.这个命令用来得到支持的频带 (GSM 900,DCS 1800 或PCS ...
随机推荐
- Java项目经验——程序员成长的关键(转载)
Java就是用来做项目的!Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点:1.掌握项目开发的基本步骤2.具备极强的面向对象的分析与设计技巧3.掌握用例驱动.以 ...
- PHP7安装问题解决
ext/standard/info.o: In function `php_info_print_request_uri’: /root/php-5.4.16/ext/standard/info.c: ...
- [Java] Serializable(序列化)的理解
1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来.虽然你可以用你自己的各种各样的方法来保存object st ...
- UITextField的简单操作和实际应用
UITestField UITestField* testField = [UITestField alloc]initWithFrame]; /* 设置边框样式 typedef NS_ENUM(NS ...
- 在ios开发中nil和NUll和Nilde区别————和如何判断连个对象的关系和UISlider不能拖动的问题
nil表示一个对象指针为空,针对对象 >示例代码: NSString *someString = nil; NSURL *someURL = nil; id someObject = nil; ...
- 重构20-Extract Subclass(提取父类)
当一个类中的某些方法并不是面向所有的类时,可以使用该重构将其迁移到子类中.我这里举的例子十分简单,它包含一个Registration类,该类处理与学生注册课程相关的所有信息. public class ...
- 剑指Offer44 扑克牌的顺子
/************************************************************************* > File Name: 44_Contin ...
- duplicate symbol _OBJC_METACLASS_$ 报错记录
duplicate symbol _OBJC_METACLASS_$_TabbarButton in: /Users/hw201406/Library/Developer/Xcode/DerivedD ...
- 【PHP基础】位运算与原码,反码,补码
对于有符号的而言: ①二进制的最高位是符号位: 0表示正数,1表示负数 ②正数的原码,反码,补码都一样 ③负数的反码=它的原码符号位不变,其它位取反(0->1,1->0) ...
- 邮箱格式验证demo
<html> <head> <script type="text/javascript"> function validate_email(fi ...