概述
在Java中操作串口实现短信收发
采用串口操作进行短信收发,是比较常见的一种方式.比如,很多群发软件,用的就是这种方法.
1.配置comm.jar.
Comm.jar是Sub实现底层串口操作的API,调用了本地的DLL文件,因为Java本身不具备直接访问硬件设置的能力,都是通过调用本地方法来实现的.可以Java的官方网站下载.下载之后把其中Comm.jar包导入到工程的Classpath中,把另外两个非常重要的文件javax.comm.properties和win32com.dll考贝到你的工程目录下,即java.user下.
2.打开串口.
在打开串口前首先要加载Win32com.dll,因为我们没有把它放到JRE路径下,所以必须要自己显式的加载.
String driverName = "com.sun.comm.Win32Driver";
CommDriver driver = null;
try {
System.loadLibrary("win32com");
driver = (CommDriver) Class.forName(driverName).newInstance();
driver.initialize();
} catch (InstantiationException e1) {
logger.error("1:" + e1.getMessage());
} catch (IllegalAccessException e1) {
logger.error("2:" + e1.getMessage());
} catch (ClassNotFoundException e1) {
logger.error(e1.getMessage());
}
然后获取你指定的端口:
SerialPort sPort = null;
CommPortIdentifier portID;
String owner = new String("modemn");
int keeptime = 5000;
Enumeration portList;
portList = CommPortIdentifier.getPortIdentifiers();
// 如果有多个端口
while (portList.hasMoreElements()) {
portID = (CommPortIdentifier) portList.nextElement();
if (portID.getName().equals(com))
try {
sPort = (SerialPort) portID.open(owner, keeptime);
break;
}// 打开一个串口
catch (PortInUseException e) {
logger.fatal(e.getMessage());
System.exit(1);
}
}// while
成功打开端口之后,设置端口的相关参数,如波特率、数据位、奇偶校验位等.这个跟具体的设备有关,不过一般情况下波特率为9600,数据位为8,停止位为1,奇偶为0,流量控制为Off:
if (sPort != null) {
logger.debug("serial name is :" + sPort.getName());
try {
// 设置串口的参数
sPort.setSerialPortParams(9600,// 波特率
SerialPort.DATABITS_8,// 数据位数
SerialPort.STOPBITS_1, // 停止位
SerialPort.PARITY_NONE);// 奇偶位
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
3.对端口进行初始化
对进行数据接收或发送之前,还要先进行一些参数的设置。重要的有:
AT+cmgf=0(设置Modem收发采用Pdu方式,1为Text方式。有些Modem可能正好相反,具体参考Modem的At指令说明)
At+cnmi=2,2,0,0,0(设置Modem自动接收,AT指令说明书给的定义是新的短消息指示说明,就是说说有了新的短消息,怎么给你提示。这个设置是有消息将自动显示,无需进行读卡操作。看到有很网上的例子都是1,1,这样还要通过读卡操作才能得到短消息,十分不方便,还降低了SIM卡的使用寿命)
At+csmp=17,167,0,240(设置短消息文本模式参数。其中17是指SMS-SUBMIT的十进制整数表达形式,即提交;167指是有效期的整数表达形式;0指的是协议标识的十进制整数表示形式。前三个参数都该命令的默认值。最后一240指是编码方案,在Text方式下发送英文和Pdu模式下一般设置成240.如果要在Text模式下发送中文,有多Modem要设成8)
对端口所作的上述初始化工作,可以在超终终端里直接设置。但最好是把它写在程序里,在程序启动之后就进行此工作,避免手工操作的麻烦。
对Modem进行初始化,就必须把上述命令输出到Modem的端口上,还要看它的反回值是不是OK。要想得到返回值,就要对COM端口进行侦听了。所以初始化的工作有三步:
第一,侦听端口
sPort.addEventListener(this);
sPort.notifyOnDataAvailable(true);
第二,建立输入输出流,把初始化命令输出到Modem的COM端口
// 用配置参数初始化MODEM
msg = conf.initParam();
if (msg != null) {
if (conf.modemMode() != null && conf.modemMode().equals("0"))
if (isPduMode)
msg = "at+cmgf=0;" + msg;
else
msg = "at+cmgf=1;" + msg;
sendMsg(msg.getBytes(), sPort);
sendOKFlag = true;
}
// 把短消息通过数据猫发送出去
private void sendMsg(byte[] msg, SerialPort sPort) {
DataOutputStream pw;
if (msg != null && sPort != null)
try {
pw = new DataOutputStream(sPort.getOutputStream());
pw.write(msg);
pw.flush();
pw.close();
logger.debug("msg has been send from Modemn:");
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}
// 处理侦听到的串口事件
public synchronized void serialEvent(SerialPortEvent ev) {
DataInputStream in;
int c = 0;
StringBuffer sb = null;
// 如果有串口事件发生
if (ev.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
in = new DataInputStream(sPort.getInputStream());
sb = new StringBuffer();
while ((c = in.read()) != -1) {
sb.append((char) c);
System.out.println(sb);
if (handleRecData(sb)) {
logger.debug("从Modem接收到的数据" + sb);
sb = new StringBuffer();
}
}
}// try
catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}
}
serialEvent事件就是刚才添加侦听之后要工作的部分。如果写过界面程序的人,对这个会比较熟悉。一但Modem回复数据,此事件就会触发。我们在发送完初始化命令之后,就从此事件中接收数据,看能不能收到OK。如果收到,就初始化成功。
1.配置comm.jar.
Comm.jar是Sub实现底层串口操作的API,调用了本地的DLL文件,因为Java本身不具备直接访问硬件设置的能力,都是通过调用本地方法来实现的.可以Java的官方网站下载.下载之后把其中Comm.jar包导入到工程的Classpath中,把另外两个非常重要的文件javax.comm.properties和win32com.dll考贝到你的工程目录下,即java.user下.
2.打开串口.
在打开串口前首先要加载Win32com.dll,因为我们没有把它放到JRE路径下,所以必须要自己显式的加载.
String driverName = "com.sun.comm.Win32Driver";
CommDriver driver = null;
try {
System.loadLibrary("win32com");
driver = (CommDriver) Class.forName(driverName).newInstance();
driver.initialize();
} catch (InstantiationException e1) {
logger.error("1:" + e1.getMessage());
} catch (IllegalAccessException e1) {
logger.error("2:" + e1.getMessage());
} catch (ClassNotFoundException e1) {
logger.error(e1.getMessage());
}
然后获取你指定的端口:
SerialPort sPort = null;
CommPortIdentifier portID;
String owner = new String("modemn");
int keeptime = 5000;
Enumeration portList;
portList = CommPortIdentifier.getPortIdentifiers();
// 如果有多个端口
while (portList.hasMoreElements()) {
portID = (CommPortIdentifier) portList.nextElement();
if (portID.getName().equals(com))
try {
sPort = (SerialPort) portID.open(owner, keeptime);
break;
}// 打开一个串口
catch (PortInUseException e) {
logger.fatal(e.getMessage());
System.exit(1);
}
}// while
成功打开端口之后,设置端口的相关参数,如波特率、数据位、奇偶校验位等.这个跟具体的设备有关,不过一般情况下波特率为9600,数据位为8,停止位为1,奇偶为0,流量控制为Off:
if (sPort != null) {
logger.debug("serial name is :" + sPort.getName());
try {
// 设置串口的参数
sPort.setSerialPortParams(9600,// 波特率
SerialPort.DATABITS_8,// 数据位数
SerialPort.STOPBITS_1, // 停止位
SerialPort.PARITY_NONE);// 奇偶位
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
3.对端口进行初始化
对进行数据接收或发送之前,还要先进行一些参数的设置。重要的有:
AT+cmgf=0(设置Modem收发采用Pdu方式,1为Text方式。有些Modem可能正好相反,具体参考Modem的At指令说明)
At+cnmi=2,2,0,0,0(设置Modem自动接收,AT指令说明书给的定义是新的短消息指示说明,就是说说有了新的短消息,怎么给你提示。这个设置是有消息将自动显示,无需进行读卡操作。看到有很网上的例子都是1,1,这样还要通过读卡操作才能得到短消息,十分不方便,还降低了SIM卡的使用寿命)
At+csmp=17,167,0,240(设置短消息文本模式参数。其中17是指SMS-SUBMIT的十进制整数表达形式,即提交;167指是有效期的整数表达形式;0指的是协议标识的十进制整数表示形式。前三个参数都该命令的默认值。最后一240指是编码方案,在Text方式下发送英文和Pdu模式下一般设置成240.如果要在Text模式下发送中文,有多Modem要设成8)
对端口所作的上述初始化工作,可以在超终终端里直接设置。但最好是把它写在程序里,在程序启动之后就进行此工作,避免手工操作的麻烦。
对Modem进行初始化,就必须把上述命令输出到Modem的端口上,还要看它的反回值是不是OK。要想得到返回值,就要对COM端口进行侦听了。所以初始化的工作有三步:
第一,侦听端口
sPort.addEventListener(this);
sPort.notifyOnDataAvailable(true);
第二,建立输入输出流,把初始化命令输出到Modem的COM端口
// 用配置参数初始化MODEM
msg = conf.initParam();
if (msg != null) {
if (conf.modemMode() != null && conf.modemMode().equals("0"))
if (isPduMode)
msg = "at+cmgf=0;" + msg;
else
msg = "at+cmgf=1;" + msg;
sendMsg(msg.getBytes(), sPort);
sendOKFlag = true;
}
// 把短消息通过数据猫发送出去
private void sendMsg(byte[] msg, SerialPort sPort) {
DataOutputStream pw;
if (msg != null && sPort != null)
try {
pw = new DataOutputStream(sPort.getOutputStream());
pw.write(msg);
pw.flush();
pw.close();
logger.debug("msg has been send from Modemn:");
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}
// 处理侦听到的串口事件
public synchronized void serialEvent(SerialPortEvent ev) {
DataInputStream in;
int c = 0;
StringBuffer sb = null;
// 如果有串口事件发生
if (ev.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
in = new DataInputStream(sPort.getInputStream());
sb = new StringBuffer();
while ((c = in.read()) != -1) {
sb.append((char) c);
System.out.println(sb);
if (handleRecData(sb)) {
logger.debug("从Modem接收到的数据" + sb);
sb = new StringBuffer();
}
}
}// try
catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}
}
serialEvent事件就是刚才添加侦听之后要工作的部分。如果写过界面程序的人,对这个会比较熟悉。一但Modem回复数据,此事件就会触发。我们在发送完初始化命令之后,就从此事件中接收数据,看能不能收到OK。如果收到,就初始化成功。
最后
以上就是自信毛豆为你收集整理的在Java中操作串口实现短信收发1的全部内容,希望文章能够帮你解决在Java中操作串口实现短信收发1所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复