歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 使用Mina模擬短信的收發

使用Mina模擬短信的收發

日期:2017/3/1 10:06:46   编辑:Linux編程

資料參考來源自李海峰,並略作修改。

Apache_Mina_Server_2.0中文參考手冊V1.0 PDF版下載

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.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. * @see M sip:wap.fetion.com.cn SIP-C/2.0 //狀態行,一般表示協議的名字、版本號等
  5. * @see S: 1580101xxxx //短信的發送號碼
  6. * @see R: 1880202xxxx //短信的接收號碼
  7. * @see L: 21 //短信的字節數
  8. * @see 你好!!Hello World!! //短信的內容
  9. * @see 上面每行的末尾使用ASCII的10(\n)作為換行符
  10. */
  11. public class SmsObject {
  12. private String sender; //短信發送者
  13. private String receiver; //短信接收者
  14. private String message; //短信內容
  15. /*三個屬性的getter和setter略*/
  16. }

下面是Mina編寫的服務端主類MyServer.java

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

下面是服務端的消息處理器ServerHandler.java

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

下面是Mina編寫的客戶端主類MyClient.java

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

下面是客戶端的消息處理器ClientHandler.java

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

下面是我們自定義的編解碼工廠類CmccSipcCodecFactory.java

  1. package com.mina.factory;
  2. import java.nio.charset.Charset;
  3. import org.apache.mina.core.session.IoSession;
  4. import org.apache.mina.filter.codec.ProtocolCodecFactory;
  5. import org.apache.mina.filter.codec.ProtocolDecoder;
  6. import org.apache.mina.filter.codec.ProtocolEncoder;
  7. import com.mina.codec.CmccSipcDecoder;
  8. import com.mina.codec.CmccSipcEncoder;
  9. /**
  10. * 自定義編解碼工廠
  11. * @see 實際上這個工廠類就是包裝了編碼器、解碼器
  12. * @see 通過接口中的getEncoder()、getDecoder()方法向ProtocolCodecFilter過濾器返回編解碼器實例
  13. * @see 以便在過濾器中對數據進行編解碼
  14. */
  15. public class CmccSipcCodecFactory implements ProtocolCodecFactory {
  16. private final CmccSipcEncoder encoder;
  17. private final CmccSipcDecoder decoder;
  18. public CmccSipcCodecFactory(){
  19. this(Charset.defaultCharset());
  20. }
  21. public CmccSipcCodecFactory(Charset charset){
  22. this.encoder = new CmccSipcEncoder(charset);
  23. this.decoder = new CmccSipcDecoder(charset);
  24. }
  25. @Override
  26. public ProtocolDecoder getDecoder(IoSession arg0) throws Exception {
  27. return decoder;
  28. }
  29. @Override
  30. public ProtocolEncoder getEncoder(IoSession arg0) throws Exception {
  31. return encoder;
  32. }
  33. }

重頭戲:下面是我們自定義的編碼器CmccSipcEncoder.java

  1. package com.mina.codec;
  2. import java.nio.charset.Charset;
  3. import java.nio.charset.CharsetEncoder;
  4. import org.apache.mina.core.buffer.IoBuffer;
  5. import org.apache.mina.core.session.IoSession;
  6. import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
  7. import org.apache.mina.filter.codec.ProtocolEncoderOutput;
  8. import com.mina.model.SmsObject;
  9. /**
  10. * 自定義編碼器
  11. * Mina中編寫編碼器可以實現ProtocolEncoder,其中有encode()、dispose()兩個方法需要實現
  12. * dispose()用於在銷毀編碼器時釋放關聯的資源,由於該方法一般我們並不關心,故通常直接繼承適配器ProtocolEncoderAdapter
  13. * @see ==============================================================================================================
  14. * @see 相比較解碼(字節轉為JAVA對象,也叫拆包)來說,編碼(Java對象轉為字節,也叫做打包)就很簡單了
  15. * @see 我們只需要把Java對象轉為指定格式的字節流,然後write()就可以了
  16. * @see ==============================================================================================================
  17. * @see 解碼器的編寫有以下幾個步驟
  18. * @see 1、將encode()方法中的message對象強制轉換為指定的對象類型
  19. * @see 2、創建IoBuffer緩沖區對象,並設置為自動擴展
  20. * @see 3、將轉換後的message對象中的各個部分按照指定的應用層協議進行組裝,並put()到IoBuffer緩沖區
  21. * @see 4、數據組裝完畢後,調用flip()方法,為輸出做好准備
  22. * @see 切記在write()方法之前調用IoBuffer的flip()方法,否則緩沖區的position的後面是沒有數據可以用來輸出的
  23. * @see 你必須調用flip()方法將position移至0,limit移至剛才的position。這個flip()方法的含義請參看java.nio.ByteBuffer
  24. * @see 5、最後調用ProtocolEncoderOutput的write()方法輸出IoBuffer緩沖區實例
  25. * @see ==============================================================================================================
  26. */
  27. public class CmccSipcEncoder extends ProtocolEncoderAdapter {
  28. private final Charset charset;
  29. public CmccSipcEncoder(Charset charset){
  30. this.charset = charset;
  31. }
  32. /**
  33. * 依據傳入的字符集類型對message對象進行編碼
  34. * 編碼的方式就是按照短信協議拼裝字符串到IoBuffer緩沖區,然後調用ProtocolEncoderOutput的write()方法輸出字節流
  35. */
  36. @Override
  37. public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {
  38. SmsObject sms = (SmsObject)message;
  39. CharsetEncoder ce = charset.newEncoder();
  40. IoBuffer buffer = IoBuffer.allocate(100).setAutoExpand(true);
  41. String statusLine = "M sip:wap.fetion.com.cn SIP-C/2.0";
  42. String sender = sms.getSender();
  43. String receiver = sms.getReceiver();
  44. String smsContent = sms.getMessage();
  45. buffer.putString(statusLine+'\n', ce);
  46. buffer.putString("S: "+sender+'\n', ce);
  47. buffer.putString("R: "+receiver+'\n', ce);
  48. //使用String類與Byte[]類型之間的轉換方法獲得轉為字節流後的字節數
  49. buffer.putString("L: "+smsContent.getBytes(charset).length+'\n', ce);
  50. buffer.putString(smsContent, ce);
  51. buffer.flip();
  52. out.write(buffer);
  53. }
  54. }
Copyright © Linux教程網 All Rights Reserved