socket通讯常见模式分析(转)

 

Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我们快速开发高性能、高扩展性的网络通信应用,Mina 提供了事件驱动、异步(Mina 的异步IO 默认使用的是JAVA NIO 作为底层支持)操作的编程模型。Mina 主要有1.x 和2.x 两个分支,这里我们讲解最新版本2.0,如果你使用的是Mina 1.x,那么可能会有一些功能并不适用。学习本文档,需要你已掌握JAVA IO、JAVA NIO、JAVASocket、JAVA 线程及并发库(java.util.concurrent.*)的知识。Mina 同时提供了网络通信的Server 端、Client 端的封装,无论是哪端,Mina 在整个网通通信结构中都处于如下的位置:

 

 

 

 

 

可见Mina 的API 将真正的网络通信与我们的应用程序隔离开来,你只需要关心你要发送、接收的数据以及你的业务逻辑即可。同样的,无论是哪端,Mina 的执行流程如下所示:

 

 

 

 

(1.) IoService:这个接口在一个线程上负责套接字的建立,拥有自己的Selector,监听是否有连接被建立。


(2.) IoProcessor:这个接口在另一个线程上负责检查是否有数据在通道上读写,也就是说它也拥有自己的Selector,这是与我们使用JAVA NIO 编码时的一个不同之处,通常在JAVA NIO 编码中,我们都是使用一个Selector,也就是不区分IoService与IoProcessor 两个功能接口。另外,IoProcessor 负责调用注册在IoService 上的过滤器,并在过滤器链之后调用IoHandler。


(3.) IoFilter:这个接口定义一组拦截器,这些拦截器可以包括日志输出、黑名单过滤、数据的编码(write 方向)与解码(read 方向)等功能,其中数据的encode 与decode是最为重要的、也是你在使用Mina 时最主要关注的地方。


(4.) IoHandler:这个接口负责编写业务逻辑,也就是接收、发送数据的地方。

 

 

 

Mina自带的过滤器(部分)

 

 

 

 

下面我们写一个 例子 :1个mina 的客户端和服务器端,完成双方的通讯,并且服务器端是使用了 mina的 BlacklistFilter 黑名单过滤器,用来防止非法的客户端的访问

 

 

 

服务器端:MinaTimeServer.java

 

 

Java代码    收藏代码
  1. package cn.com.xinli.mina;  
  2. import java.io.IOException;  
  3. import java.net.InetAddress;  
  4. import java.net.InetSocketAddress;  
  5. import java.nio.charset.Charset;  
  6. import java.util.Date;  
  7.   
  8. import org.apache.mina.core.service.IoAcceptor;  
  9. import org.apache.mina.core.service.IoHandlerAdapter;  
  10. import org.apache.mina.core.session.IdleStatus;  
  11. import org.apache.mina.core.session.IoSession;  
  12. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  13. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
  14. import org.apache.mina.filter.firewall.BlacklistFilter;  
  15. import org.apache.mina.filter.logging.LoggingFilter;  
  16. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
  17.   
  18. public class MinaTimeServer {     
  19.     
  20.     public static final int PORT = 9123;     
  21.      
  22.     public static void main(String[] args)throws IOException {     
  23.              
  24.         IoAcceptor acceptor = new NioSocketAcceptor();     
  25.         BlacklistFilter blacklistFilter=new BlacklistFilter();  
  26.         InetAddress[] address= new InetAddress[1];  
  27.         address[0]=InetAddress.getByName("169.254.11.186");  
  28.         blacklistFilter.setBlacklist(address);  
  29.         acceptor.getFilterChain().addFirst("black",blacklistFilter);   
  30.         acceptor.getFilterChain().addLast("logger"new LoggingFilter());   
  31.           
  32.         acceptor.getFilterChain().addLast("codec"new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("GBK"))));     
  33.         acceptor.setHandler(new TimeServerHandler());     
  34.           
  35.         acceptor.getSessionConfig().setReadBufferSize(2048);     
  36.         acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);     
  37.              
  38.         acceptor.bind(new InetSocketAddress(PORT));     
  39.           
  40.         System.out.println("MINA Time Server started,bind port:"+PORT);     
  41.     }     
  42. }     
  43.     
  44. class TimeServerHandler extends IoHandlerAdapter     
  45. {     
  46.       
  47.     @Override   
  48.     public void exceptionCaught(IoSession session,Throwable cause)throws Exception     
  49.     {     
  50.           
  51.         cause.printStackTrace();     
  52.     }   
  53.       
  54.       
  55.     @Override    
  56.     public void messageReceived(IoSession session,Object message)throws Exception     
  57.     {     
  58.           
  59.         String str = message.toString();    
  60.         System.out.println("str:"+str);  
  61.         if(str.trim().equalsIgnoreCase("quit"))     
  62.         {     
  63.             session.close(true);    
  64.             return;     
  65.         }     
  66.         Date date = new Date();     
  67.         session.write(date.toString());     
  68.         System.out.println("Message written...");  
  69.         session.close(true);  
  70.     }     
  71.     @Override    
  72.     public void sessionIdle(IoSession session,IdleStatus status)throws Exception     
  73.     {     
  74.         System.out.println("IDLE " + session.getIdleCount(status));     
  75.     }  
  76.   
  77.   
  78.     @Override  
  79.     public void messageSent(IoSession session, Object message) throws Exception  
  80.     {  
  81.         // TODO Auto-generated method stub  
  82.         super.messageSent(session, message);  
  83.     }     
  84. }    

 

客户端:MinaTimeClinet.java

 

Java代码    收藏代码
  1. package cn.com.xinli.mina;  
  2. import java.net.InetSocketAddress;  
  3. import java.nio.charset.Charset;  
  4.   
  5. import org.apache.mina.core.service.IoConnector;  
  6. import org.apache.mina.core.service.IoHandlerAdapter;  
  7. import org.apache.mina.core.session.IoSession;  
  8. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
  9. import org.apache.mina.filter.codec.textline.LineDelimiter;  
  10. import org.apache.mina.filter.codec.textline.TextLineCodecFactory;  
  11. import org.apache.mina.filter.firewall.BlacklistFilter;  
  12. import org.apache.mina.transport.socket.nio.NioSocketConnector;  
  13. import org.slf4j.Logger;  
  14. import org.slf4j.LoggerFactory;  
  15.   
  16.   
  17. public class MinaTimeClinet  
  18. {  
  19.     public static void main(String[] args)  
  20.     {  
  21.         IoConnector connector=new NioSocketConnector();  
  22.         connector.setConnectTimeoutMillis(30000);  
  23.         connector.getFilterChain().addLast("codec",  
  24.         new ProtocolCodecFilter(  
  25.         new TextLineCodecFactory(  
  26.         Charset.forName("GBK")  
  27. //      LineDelimiter.WINDOWS.getValue(),  
  28. //      LineDelimiter.WINDOWS.getValue()  
  29.         )  
  30.         )  
  31.         );  
  32.           
  33.         connector.setHandler(new ClientHandler("你好!\r\n 大家好!"));  
  34.       
  35.         connector.connect(new InetSocketAddress("localhost"9123));  
  36.         connector.dispose();  
  37.           
  38.           
  39.         }  
  40.   
  41.           
  42.       
  43. }  
  44. class ClientHandler extends IoHandlerAdapter   
  45. {  
  46.       
  47.     private final String values;  
  48.     public ClientHandler(String values)  
  49.     {  
  50.         this.values = values;  
  51.     }  
  52.     @Override  
  53.     public void sessionOpened(IoSession session)  
  54.     {  
  55.           
  56.         session.write(values);  
  57.         //session.close(true);  
  58.         //return;  
  59.     }  
  60.       
  61. }  

 

 

 运行结果:

 

MINA Time Server started,bind port:9123
0    [NioProcessor-1] INFO  org.apache.mina.filter.logging.LoggingFilter(158) - CREATED
0    [NioProcessor-1] INFO  org.apache.mina.filter.logging.LoggingFilter(158) - OPENED
63   [NioProcessor-1] INFO  org.apache.mina.filter.logging.LoggingFilter(140) - RECEIVED: HeapBuffer[pos=0 lim=18 cap=2048: C4 E3 BA C3 A3 A1 0D 0A 20 B4 F3 BC D2 BA C3 A3...]
str:你好!
Message written...
str: 大家好!
Message written...
94   [NioProcessor-1] INFO  org.apache.mina.filter.logging.LoggingFilter(140) - SENT: HeapBuffer[pos=0 lim=29 cap=32: 53 75 6E 20 4A 61 6E 20 31 30 20 31 33 3A 33 37...]
94   [NioProcessor-1] INFO  org.apache.mina.filter.logging.LoggingFilter(140) - SENT: HeapBuffer[pos=0 lim=0 cap=0: empty]
125  [NioProcessor-1] INFO  org.apache.mina.filter.logging.LoggingFilter(158) - CLOSED

 

如果客户端使用的黑名单中的IP,则服务器端 拒绝连接:

 

 

MINA Time Server started,bind port:9123
0    [NioProcessor-1] WARN  org.apache.mina.filter.firewall.BlacklistFilter(230) - Remote address in the blacklist; closing.
0    [NioProcessor-1] WARN  org.apache.mina.filter.firewall.BlacklistFilter(230) - Remote address in the blacklist; closing.
0    [NioProcessor-1] WARN  org.apache.mina.filter.firewall.BlacklistFilter(230) - Remote address in the blacklist; closing.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值