使用Mina模拟短信的收发


资料参考来源自李海峰,并略作修改。

Apache_Mina_Server_2.0中文参考手册V1.0 PDF版下载

免费下载地址在 http://linux.bkjia.com/

用户名与密码都是www.bkjia.com

具体下载目录在 /2012年资料/11月/24日/使用Mina模拟短信的收发/Apache_Mina_Server_2.0中文参考手册V1.0 PDF版

This is Apache Mina 2.0.4, Let`s drink code....


下面是用于模拟短信协议内容的实体类

  1. package com.mina.model; 
  2.  
  3. /** 
  4.  * 模拟短信协议内容的对象 
  5.  * @see M sip:wap.fetion.com.cn SIP-C/2.0 //状态行,一般表示协议的名字、版本号等 
  6.  * @see S: 1580101xxxx                    //短信的发送号码 
  7.  * @see R: 1880202xxxx                    //短信的接收号码 
  8.  * @see L: 21                             //短信的字节数 
  9.  * @see 你好!!Hello World!!               //短信的内容 
  10.  * @see 上面每行的末尾使用ASCII的10(\n)作为换行符 
  11.  */ 
  12. public class SmsObject { 
  13.     private String sender;   //短信发送者  
  14.     private String receiver; //短信接收者  
  15.     private String message;  //短信内容  
  16.     /*三个属性的getter和setter略*/ 

下面是Mina编写的服务端主类MyServer.java

  1. package com.mina.server; 
  2.  
  3. import java.io.IOException; 
  4. import java.net.InetSocketAddress; 
  5. import java.nio.charset.Charset; 
  6.  
  7. import org.apache.mina.core.service.IoAcceptor; 
  8. import org.apache.mina.core.session.IdleStatus; 
  9. import org.apache.mina.filter.codec.ProtocolCodecFilter; 
  10. import org.apache.mina.transport.socket.nio.NioSocketAcceptor; 
  11.  
  12. import com.mina.factory.CmccSipcCodecFactory; 
  13.  
  14. public class MyServer { 
  15.     public static void main(String[] args) throws IOException { 
  16.         IoAcceptor acceptor = new NioSocketAcceptor(); 
  17.         acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10); 
  18.         acceptor.getFilterChain().addLast("codec"new ProtocolCodecFilter(new CmccSipcCodecFactory(Charset.forName("UTF-8")))); 
  19.         acceptor.setHandler(new ServerHandler()); 
  20.         acceptor.bind(new InetSocketAddress(9876)); 
  21.         System.out.println("Mina Server is Listing on := 9876"); 
  22.     } 

下面是服务端的消息处理器ServerHandler.java

  1. package com.mina.server; 
  2.  
  3. import org.apache.mina.core.service.IoHandlerAdapter; 
  4. import org.apache.mina.core.session.IoSession; 
  5.  
  6. import com.mina.model.SmsObject; 
  7.  
  8. public class ServerHandler extends IoHandlerAdapter { 
  9.     @Override 
  10.     public void messageReceived(IoSession session, Object message) throws Exception { 
  11.         SmsObject sms = (SmsObject)message; 
  12.         System.out.println("The message received from Client is [" + sms.getMessage() + "]"); 
  13.     } 
  14.     @Override 
  15.     public void sessionOpened(IoSession session) throws Exception{ 
  16.         System.out.println("InComing Client:" + session.getRemoteAddress()); 
  17.     } 

下面是Mina编写的客户端主类MyClient.java

  1. package com.mina.client; 
  2.  
  3. import java.net.InetSocketAddress; 
  4. import java.nio.charset.Charset; 
  5.  
  6. import org.apache.mina.core.service.IoConnector; 
  7. import org.apache.mina.filter.codec.ProtocolCodecFilter; 
  8. import org.apache.mina.transport.socket.nio.NioSocketConnector; 
  9.  
  10. import com.mina.factory.CmccSipcCodecFactory; 
  11.  
  12. public class MyClient { 
  13.     public static void main(String[] args) { 
  14.         IoConnector connector = new NioSocketConnector(); 
  15.         connector.setConnectTimeoutMillis(3000); 
  16.         connector.getFilterChain().addLast("codec"new ProtocolCodecFilter(new CmccSipcCodecFactory(Charset.forName("UTF-8")))); 
  17.         connector.setHandler(new ClientHandler()); 
  18.         connector.connect(new InetSocketAddress("localhost"9876)); 
  19.     } 
  20. }

下面是客户端的消息处理器ClientHandler.java

  1. package com.mina.client; 
  2.  
  3. import org.apache.mina.core.service.IoHandlerAdapter; 
  4. import org.apache.mina.core.session.IoSession; 
  5.  
  6. import com.mina.model.SmsObject; 
  7.  
  8. public class ClientHandler extends IoHandlerAdapter { 
  9.     @Override 
  10.     public void sessionOpened(IoSession session) throws Exception { 
  11.         SmsObject sms = new SmsObject(); 
  12.         sms.setSender("15025302990"); 
  13.         sms.setReceiver("13716700602"); 
  14.         sms.setMessage("Hi Jadyer,这是我用Mina2.x发给你的消息...."); 
  15.         session.write(sms); 
  16.     } 

下面是我们自定义的编解码工厂类CmccSipcCodecFactory.java

  1. package com.mina.factory; 
  2.  
  3. import java.nio.charset.Charset; 
  4.  
  5. import org.apache.mina.core.session.IoSession; 
  6. import org.apache.mina.filter.codec.ProtocolCodecFactory; 
  7. import org.apache.mina.filter.codec.ProtocolDecoder; 
  8. import org.apache.mina.filter.codec.ProtocolEncoder; 
  9.  
  10. import com.mina.codec.CmccSipcDecoder; 
  11. import com.mina.codec.CmccSipcEncoder; 
  12.  
  13. /** 
  14.  * 自定义编解码工厂 
  15.  * @see 实际上这个工厂类就是包装了编码器、解码器 
  16.  * @see 通过接口中的getEncoder()、getDecoder()方法向ProtocolCodecFilter过滤器返回编解码器实例 
  17.  * @see 以便在过滤器中对数据进行编解码 
  18.  */ 
  19. public class CmccSipcCodecFactory implements ProtocolCodecFactory { 
  20.     private final CmccSipcEncoder encoder; 
  21.     private final CmccSipcDecoder decoder; 
  22.     public CmccSipcCodecFactory(){ 
  23.         this(Charset.defaultCharset()); 
  24.     } 
  25.     public CmccSipcCodecFactory(Charset charset){ 
  26.         this.encoder = new CmccSipcEncoder(charset); 
  27.         this.decoder = new CmccSipcDecoder(charset); 
  28.     } 
  29.     @Override 
  30.     public ProtocolDecoder getDecoder(IoSession arg0) throws Exception { 
  31.         return decoder; 
  32.     } 
  33.     @Override 
  34.     public ProtocolEncoder getEncoder(IoSession arg0) throws Exception { 
  35.         return encoder; 
  36.     } 

重头戏:下面是我们自定义的编码器CmccSipcEncoder.java

  1. package com.mina.codec; 
  2.  
  3. import java.nio.charset.Charset; 
  4. import java.nio.charset.CharsetEncoder; 
  5.  
  6. import org.apache.mina.core.buffer.IoBuffer; 
  7. import org.apache.mina.core.session.IoSession; 
  8. import org.apache.mina.filter.codec.ProtocolEncoderAdapter; 
  9. import org.apache.mina.filter.codec.ProtocolEncoderOutput; 
  10.  
  11. import com.mina.model.SmsObject; 
  12.  
  13. /** 
  14.  * 自定义编码器 
  15.  * Mina中编写编码器可以实现ProtocolEncoder,其中有encode()、dispose()两个方法需要实现 
  16.  * dispose()用于在销毁编码器时释放关联的资源,由于该方法一般我们并不关心,故通常直接继承适配器ProtocolEncoderAdapter 
  17.  * @see ============================================================================================================== 
  18.  * @see 相比较解码(字节转为JAVA对象,也叫拆包)来说,编码(Java对象转为字节,也叫做打包)就很简单了 
  19.  * @see 我们只需要把Java对象转为指定格式的字节流,然后write()就可以了 
  20.  * @see ============================================================================================================== 
  21.  * @see 解码器的编写有以下几个步骤 
  22.  * @see 1、将encode()方法中的message对象强制转换为指定的对象类型 
  23.  * @see 2、创建IoBuffer缓冲区对象,并设置为自动扩展 
  24.  * @see 3、将转换后的message对象中的各个部分按照指定的应用层协议进行组装,并put()到IoBuffer缓冲区 
  25.  * @see 4、数据组装完毕后,调用flip()方法,为输出做好准备 
  26.  * @see    切记在write()方法之前调用IoBuffer的flip()方法,否则缓冲区的position的后面是没有数据可以用来输出的 
  27.  * @see    你必须调用flip()方法将position移至0,limit移至刚才的position。这个flip()方法的含义请参看java.nio.ByteBuffer 
  28.  * @see 5、最后调用ProtocolEncoderOutput的write()方法输出IoBuffer缓冲区实例 
  29.  * @see ============================================================================================================== 
  30.  */ 
  31. public class CmccSipcEncoder extends ProtocolEncoderAdapter { 
  32.     private final Charset charset; 
  33.     public CmccSipcEncoder(Charset charset){ 
  34.         this.charset = charset; 
  35.     } 
  36.  
  37.     /** 
  38.      * 依据传入的字符集类型对message对象进行编码 
  39.      * 编码的方式就是按照短信协议拼装字符串到IoBuffer缓冲区,然后调用ProtocolEncoderOutput的write()方法输出字节流 
  40.      */ 
  41.     @Override 
  42.     public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { 
  43.         SmsObject sms = (SmsObject)message; 
  44.         CharsetEncoder ce = charset.newEncoder(); 
  45.         IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true); 
  46.         String statusLine = "M sip:wap.fetion.com.cn SIP-C/2.0"
  47.         String sender = sms.getSender(); 
  48.         String receiver = sms.getReceiver(); 
  49.         String smsContent = sms.getMessage(); 
  50.         buffer.putString(statusLine+'\n', ce); 
  51.         buffer.putString("S: "+sender+'\n', ce); 
  52.         buffer.putString("R: "+receiver+'\n', ce); 
  53.         //使用String类与Byte[]类型之间的转换方法获得转为字节流后的字节数  
  54.         buffer.putString("L: "+smsContent.getBytes(charset).length+'\n', ce); 
  55.         buffer.putString(smsContent, ce); 
  56.         buffer.flip(); 
  57.         out.write(buffer); 
  58.     } 
  • 1
  • 2
  • 下一页

相关内容

    暂无相关文章