`
wuce7758
  • 浏览: 177503 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
  • YTT1121: 有网络拓扑发现的源代码么?能不能发我一份学习一下,现在我正要做 ...
    java拓扑图
  • YTT1121: 大神,有网络拓扑发现的源代码么?或者您会编写么?我需要做科研改 ...
    java拓扑图
  • YTT1121: 大神,有网络拓扑发现的源代码么?或者您会编写么?我需要做科研改 ...
    java拓扑图
  • poettang: 求代码分享学习,谢谢!膜拜大神!258026921@qq.co ...
    java拓扑图
  • oiqio: 87836238@qq.com,感谢楼主,来一份~
    java拓扑图

在Java中操作串口实现短信收发1

阅读更多

在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。如果收到,就初始化成功。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics