使用Mina模拟短信的收发

时间:2022-09-25 20:32:59

参考网站:http://blog.csdn.net/jadyer/article/details/8088928


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


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

[java] view plaincopyprint?
  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略*/  
  17. }  

下面是Mina编写的服务端主类MyServer.java [java] view plaincopyprint?
  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.     }  
  23. }  

下面是服务端的消息处理器ServerHandler.java [java] view plaincopyprint?
  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.     }  
  18. }  

下面是Mina编写的客户端主类MyClient.java [java] view plaincopyprint?
  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 [java] view plaincopyprint?
  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.     }  
  17. }  

下面是我们自定义的编解码工厂类CmccSipcCodecFactory.java [java] view plaincopyprint?
  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.     }  
  37. }  

重头戏:下面是我们自定义的编码器CmccSipcEncoder.java [java] view plaincopyprint?
  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.     }  
  59. }  

重头戏:最后是我们自定义的解码器CmccSipcDecoder.java [java] view plaincopyprint?
  1. package com.mina.codec;  
  2.   
  3. import java.nio.charset.Charset;  
  4. import java.nio.charset.CharsetDecoder;  
  5.   
  6. import org.apache.mina.core.buffer.IoBuffer;  
  7. import org.apache.mina.core.session.AttributeKey;  
  8. import org.apache.mina.core.session.IoSession;  
  9. import org.apache.mina.filter.codec.CumulativeProtocolDecoder;  
  10. import org.apache.mina.filter.codec.ProtocolDecoderOutput;  
  11.   
  12. import com.mina.model.SmsObject;  
  13.   
  14. /** 
  15.  * 自定义解码器 
  16.  * Mina中编写解码器,可以实现ProtocolDecoder接口,其中有decode()、finishDecode()、dispose()三个方法 
  17.  * finishDecode()用于处理IoSession关闭时剩余的未读取数据,该方法通常不会被用到,不过也可忽略处理剩余的数据 
  18.  * 同样的,一般情况下,我们只需要继承适配器ProtocolDecoderAdapter,关注decode()方法即可 
  19.  * @see ============================================================================================================= 
  20.  * @see 解码器相对编码器来说,最麻烦的是数据发送过来的规模。比如聊天室中每隔一段时间都会有聊天内容发送过来 
  21.  * @see 此时  decode()方法会被往复调用,这样处理时就会非常麻烦,幸好Mina提供了CumulativeProtocolDecoder类 
  22.  * @see 它是累积性的协议解码器。即只要有数据发送过来,该类就会去读取数据,然后累积到内部的IoBuffer缓冲区 
  23.  * @see 但具体的拆包(把累积到缓冲区的数据解码为Java对象)则交由子类的doDecode()方法完成 
  24.  * @see 实际上CumulativeProtocolDecoder就是在decode()中反复的调用暴漏给子类实现的doDecode()方法 
  25.  * @see ============================================================================================================= 
  26.  * @see 具体执行过程如下所示 
  27.  * @see 1、这里的doDecode()方法返回true时 
  28.  * @see    CumulativeProtocolDecoder的decode()方法首先会判断你是否在doDecode()方法中从内部的IoBuffer缓冲区读取了数据 
  29.  * @see    如果没有,则会抛出非法的状态异常 
  30.  * @see    即doDecode()返回true就表示你已经消费了本次数据(相当于聊天室中一个完整的消息已经读取完毕) 
  31.  * @see    进一步说,也就是此时你必须已经消费过内部的IoBuffer缓冲区的数据(哪怕是消费了一个字节的数据) 
  32.  * @see    如果验证通过,那么CumulativeProtocolDecoder会检查缓冲区内是否还有数据未读取 
  33.  * @see    如果有就继续调用doDecode()方法,没有则停止对doDecode()方法的调用,直到有新的数据被缓冲 
  34.  * @see 2、当doDecode()方法返回false时,CumulativeProtocolDecoder会停止对doDecode()的调用 
  35.  * @see    但这时,若本次数据还有未读取完的,那么就将含有剩余数据的IoBuffer缓冲区保存到IoSession中 
  36.  * @see    以便下一次数据到来时可以从IoSession中提取合并 
  37.  * @see    若发现本次数据全都读取完毕,则清空IoBuffer缓冲区 
  38.  * @see ============================================================================================================= 
  39.  * @see 简而言之,当你认为读取到的数据已经够解码了,那么就返回true,否则就返回false 
  40.  * @see 这个CumulativeProtocolDecoder其实最重要的工作就是帮你完成了数据的累积,因为这个工作是很烦琐的 
  41.  * @see ============================================================================================================= 
  42.  * @see 假如数据的发送被拆成了多次(譬如:短信协议的短信内容、消息报头被拆成了两次数据发送),那么上面的代码势必就会存在问题 
  43.  * @see 因为当第二次调用doDecode()方法时,状态变量i、matchCount势必会被重置,也就是原来的状态值并没有被保存 
  44.  * @see 那么我们如何解决状态保存的问题呢 
  45.  * @see 答案就是将状态变量保存在IoSession中或者是Decoder实例自身,但推荐使用前者 
  46.  * @see 因为虽然Decoder是单例的,其中的实例变量保存的状态在Decoder实例销毁前始终保持 
  47.  * @see 但Mina并不保证每次调用doDecode()方法时都是同一个线程 
  48.  * @see 这也就是说第一次调用doDecode()是IoProcessor-1线程,第二次有可能就是IoProcessor-2线程 
  49.  * @see 这就会产生多线程中的实例变量的可视性(Visibility,具体请参考Java的多线程知识)问题 
  50.  * @see 而IoSession中使用一个同步的HashMap保存对象,所以我们就不需要担心多线程带来的问题 
  51.  * @see ============================================================================================================= 
  52.  * @see 使用IoSession保存解码器的状态变量通常的写法如下所示 
  53.  * @see 1、在解码器中定义私有的内部类Context,然后将需要保存的状态变量定义在Context中存储 
  54.  * @see 2、在解码器中定义方法获取这个Context的实例,这个方法的实现要优先从IoSession中获取Context 
  55.  * @see ============================================================================================================= 
  56.  * @see 这里做了如下的几步操作 
  57.  * @see 1、所有记录状态的变量移到了Context内部类中,包括记录读到短信协议的哪一行的line 
  58.  * @see    每一行读取了多少个字节的matchCount,还有记录解析好的状态行、发送者、接受者、短信内容、累积数据的innerBuffer等 
  59.  * @see    这样就可以在数据不能完全解码,等待下一次doDecode()方法的调用时,还能承接上一次调用的数据 
  60.  * @see 2、在doDecode()方法中主要的变化是各种状态变量首先是从Context中获取,然后操作之后,将最新的值setXXX()到Context中保存 
  61.  * @see 3、这里注意doDecode()方法最后的判断,当认为不够解码为一条短信息时,返回false,即在本次数据流解码中不要再调用doDecode()方法 
  62.  * @see   当认为已解码出一条短信息时,输出消息并重置所有状态变量,返回true,即若本次数据流解码中还有没解码完的数据,则继续调用doDecode() 
  63.  * @see ============================================================================================================= 
  64.  */  
  65. //public class CmccSipcDecoder extends CumulativeProtocolDecoder {  
  66. //  private final Charset charset;  
  67. //  public CmccSipcDecoder(Charset charset){  
  68. //      this.charset = charset;  
  69. //  }  
  70. //  @Override  
  71. //  protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {  
  72. //      IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true);  
  73. //      CharsetDecoder cd = charset.newDecoder();  
  74. //      int i = 1;          //记录解析到了短信协议中的哪一行(\n)  
  75. //      int matchCount = 0; //记录在当前行中读取到了哪一个字节  
  76. //      String statusLine="", sender="", receiver="", length="", sms="";  
  77. //      while(in.hasRemaining()){  
  78. //          byte b = in.get();  
  79. //          buffer.put(b);  
  80. //          if(10==b && 5>i){ //10==b表示换行:该短信协议解码器使用\n(ASCII的10字符)作为分解点  
  81. //              matchCount++;  
  82. //              if(1 == i){  
  83. //                  buffer.flip(); //limit=position,position=0  
  84. //                  statusLine = buffer.getString(matchCount, cd);  
  85. //                  statusLine = statusLine.substring(0, statusLine.length()-1); //移除本行的最后一个换行符  
  86. //                  matchCount = 0; //本行读取完毕,所以让matchCount=0  
  87. //                  buffer.clear();  
  88. //              }  
  89. //              if(2 == i){  
  90. //                  buffer.flip();  
  91. //                  sender = buffer.getString(matchCount, cd);  
  92. //                  sender = sender.substring(0, sender.length()-1);  
  93. //                  matchCount = 0;  
  94. //                  buffer.clear();  
  95. //              }  
  96. //              if(3 == i){  
  97. //                  buffer.flip();  
  98. //                  receiver = buffer.getString(matchCount, cd);  
  99. //                  receiver = receiver.substring(0, receiver.length()-1);  
  100. //                  matchCount = 0;  
  101. //                  buffer.clear();  
  102. //              }  
  103. //              if(4 == i){  
  104. //                  buffer.flip();  
  105. //                  length = buffer.getString(matchCount, cd);  
  106. //                  length = length.substring(0, length.length()-1);  
  107. //                  matchCount = 0;  
  108. //                  buffer.clear();  
  109. //              }  
  110. //              i++;  
  111. //          }else if(5 == i){  
  112. //              matchCount++;  
  113. //              if(Long.parseLong(length.split(": ")[1]) == matchCount){  
  114. //                  buffer.flip();  
  115. //                  sms = buffer.getString(matchCount, cd);  
  116. //                  i++;  
  117. //                  break;  
  118. //              }  
  119. //          }else{  
  120. //              matchCount++;  
  121. //          }  
  122. //      }  
  123. //      SmsObject smsObject = new SmsObject();  
  124. //      smsObject.setSender(sender.split(": ")[1]);  
  125. //      smsObject.setReceiver(receiver.split(": ")[1]);  
  126. //      smsObject.setMessage(sms);  
  127. //      out.write(smsObject);  
  128. //      return false; //告诉Mina:本次数据已全部读取完毕,故返回false  
  129. //  }  
  130. //}  
  131. /** 
  132.  * 以上注释的解码器,适用于客户端发送的数据是一次全部发送完整的情况 
  133.  * 下面的这个解码器,适用于客户端发送的数据被拆分为多次后发送的情况 
  134.  */  
  135. public class CmccSipcDecoder extends CumulativeProtocolDecoder {  
  136.     private final Charset charset;  
  137.     private final AttributeKey CONTEXT = new AttributeKey(getClass(), "context");  
  138.     public CmccSipcDecoder(Charset charset){  
  139.         this.charset = charset;  
  140.     }  
  141.     private Context getContext(IoSession session){  
  142.         Context context = (Context)session.getAttribute(CONTEXT);  
  143.         if(null == context){  
  144.             context = new Context();  
  145.             session.setAttribute(CONTEXT, context);  
  146.         }  
  147.         return context;  
  148.     }  
  149.       
  150.     @Override  
  151.     protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {  
  152.         CharsetDecoder cd = charset.newDecoder();  
  153.         Context ctx = this.getContext(session);  
  154.         IoBuffer buffer = ctx.innerBuffer;  
  155.         int matchCount = ctx.getMatchCount();  
  156.         int line = ctx.getLine();  
  157.         String statusLine = ctx.getStatusLine();  
  158.         String sender = ctx.getSender();  
  159.         String receiver = ctx.getReceiver();  
  160.         String length = ctx.getLength();  
  161.         String sms = ctx.getSms();  
  162.         while(in.hasRemaining()){  
  163.             byte b = in.get();  
  164.             matchCount++;  
  165.             buffer.put(b);  
  166.             if(10==b && line<4){  
  167.                 if(0 == line){  
  168.                     buffer.flip();  
  169.                     statusLine = buffer.getString(matchCount, cd);  
  170.                     statusLine = statusLine.substring(0, statusLine.length()-1);  
  171.                     matchCount = 0;  
  172.                     buffer.clear();  
  173.                     ctx.setStatusLine(statusLine);  
  174.                 }  
  175.                 if(1 == line){  
  176.                     buffer.flip();  
  177.                     sender = buffer.getString(matchCount, cd);  
  178.                     sender = sender.substring(0, sender.length()-1);  
  179.                     matchCount = 0;  
  180.                     buffer.clear();  
  181.                     ctx.setSender(sender);  
  182.                 }  
  183.                 if(2 == line){  
  184.                     buffer.flip();  
  185.                     receiver = buffer.getString(matchCount, cd);  
  186.                     receiver = receiver.substring(0, receiver.length()-1);  
  187.                     matchCount = 0;  
  188.                     buffer.clear();  
  189.                     ctx.setReceiver(receiver);  
  190.                 }  
  191.                 if(3 == line){  
  192.                     buffer.flip();  
  193.                     length = buffer.getString(matchCount, cd);  
  194.                     length = length.substring(0, length.length()-1);  
  195.                     matchCount = 0;  
  196.                     buffer.clear();  
  197.                     ctx.setLength(length);  
  198.                 }  
  199.                 line++;  
  200.             }else if(4 == line){  
  201.                 if(Long.parseLong(length.split(": ")[1]) == matchCount){  
  202.                     buffer.flip();  
  203.                     sms = buffer.getString(matchCount, cd);  
  204.                     ctx.setSms(sms);  
  205.                     ctx.setMatchCount(matchCount); //由于下面的break,这里需要调用else外面的两行代码  
  206.                     ctx.setLine(line);  
  207.                     break;  
  208.                 }  
  209.             }  
  210.             ctx.setMatchCount(matchCount);  
  211.             ctx.setLine(line);  
  212.         }  
  213.         //判断本次是否已读取完毕:要求读取到最后一行,且读取的字节数与前一行指定的字节数相同  
  214.         if(4==ctx.getLine() && Long.parseLong(ctx.getLength().split(": ")[1])==ctx.getMatchCount()){  
  215.             SmsObject smsObject = new SmsObject();  
  216.             smsObject.setSender(sender.split(": ")[1]);  
  217.             smsObject.setReceiver(receiver.split(": ")[1]);  
  218.             smsObject.setMessage(sms);  
  219.             out.write(smsObject);  
  220.             ctx.reset();  
  221.             return true;  
  222.         }else{  
  223.             return false;  
  224.         }  
  225.     }  
  226.       
  227.       
  228.     private class Context{  
  229.         private final IoBuffer innerBuffer; //用于累积数据的IoBuffer  
  230.         private String statusLine = "";     //记录解析好的状态行  
  231.         private String sender = "";         //记录解析好的发送者  
  232.         private String receiver = "";       //记录解析好的接受者  
  233.         private String length = "";  
  234.         private String sms = "";            //记录解析好的短信内容  
  235.         private int matchCount = 0;         //记录每一行读取了多少个字节  
  236.         private int line = 0;               //记录读到短信协议的哪一行  
  237.         public Context(){  
  238.             innerBuffer = IoBuffer.allocate(100).setAutoExpand(true);  
  239.         }  
  240.         public String getStatusLine() {  
  241.             return statusLine;  
  242.         }  
  243.         public void setStatusLine(String statusLine) {  
  244.             this.statusLine = statusLine;  
  245.         }  
  246.         public String getSender() {  
  247.             return sender;  
  248.         }  
  249.         public void setSender(String sender) {  
  250.             this.sender = sender;  
  251.         }  
  252.         public String getReceiver() {  
  253.             return receiver;  
  254.         }  
  255.         public void setReceiver(String receiver) {  
  256.             this.receiver = receiver;  
  257.         }  
  258.         public String getLength() {  
  259.             return length;  
  260.         }  
  261.         public void setLength(String length) {  
  262.             this.length = length;  
  263.         }  
  264.         public String getSms() {  
  265.             return sms;  
  266.         }  
  267.         public void setSms(String sms) {  
  268.             this.sms = sms;  
  269.         }  
  270.         public int getMatchCount() {  
  271.             return matchCount;  
  272.         }  
  273.         public void setMatchCount(int matchCount) {  
  274.             this.matchCount = matchCount;  
  275.         }  
  276.         public int getLine() {  
  277.             return line;  
  278.         }  
  279.         public void setLine(int line) {  
  280.             this.line = line;  
  281.         }  
  282.         public void reset(){  
  283.             this.innerBuffer.clear();  
  284.             this.statusLine = "";  
  285.             this.sender = "";  
  286.             this.receiver = "";  
  287.             this.length = "";  
  288.             this.sms = "";  
  289.             this.matchCount = 0;  
  290.             this.line = 0;  
  291.         }  
  292.     }  
  293. }  
一句话总结:最为核心部分就是编码器和解码器