zoukankan      html  css  js  c++  java
  • java-mina(nio 框架)

    mina是对nio的具体实现。是目前比较高效和流行的nio框架了。

    下面是对使用mina进行通讯的一个简单demo,后面再用mina写一个RPC的简单框架。
     
    mina主要包括:
    (使用的mina版本为2.0.0.M4 core,具体可见官方网站 )
    mina也分服务端和客户端(这是肯定的...)
     
    其中服务端为:NioSocketAcceptor
    客户端为:NioSocketConnector
     
    类似于Socket的服务端跟客户端Socket。除了这些用来基本通讯的之外,还有一些可以用来处理通讯中的操作类。就是在客户端和服务端的一个个filter。这些filter可以用来进行解码,编码,可以配置日志信息,可以设定序列化类型,等等。
    另外为客户端和服务端都可以绑定一个IoHnadler,用来处理连接session在打开,收到信息,关闭等状态时候可以进行的动作。

     
    现在就来使用mina进行一个简单的客户端上传文件的demo的实现:
    demo实现的思想为:
    客 户端跟服务端建立起来连接,客户端每次想服务端传输一定大小的文件内容。(byte的方式),然后服务端接收这些byte,将其output出来,形成文 件。客户端发送完毕后,传递一个完毕的标志,这里可以传个字符串”finish“,然后服务器收到这个结束标志,在写文件结束后,再传输个成功的标志给客 户端,(字符串”success“)然后客户端关闭连接。

    服务端:
    代码比较简单。
     
    Java代码  收藏代码
    1. import java.net.InetSocketAddress;  
    2. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
    3. import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;  
    4. import org.apache.mina.filter.logging.LoggingFilter;  
    5. import org.apache.mina.transport.socket.nio.NioSocketAcceptor;  
    6.   
    7.   
    8. public class Main {  
    9.  private static final int PORT = 8080;  
    10.   
    11.  public static void main(String[] args) throws Exception {  
    12.  //服务端的实例  
    13.  NioSocketAcceptor accept=new NioSocketAcceptor();  
    14.  //添加filter,codec为序列化方式。这里为对象序列化方式,即表示传递的是对象。  
    15.  accept.getFilterChain().addLast("codec",  
    16.  new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));  
    17.                 //添加filter,日志信息  
    18.  accept.getFilterChain().addLast("logging", new LoggingFilter());  
    19.  //设置服务端的handler  
    20.  accept.setHandler(new FileUploadHandler());  
    21.  //绑定ip  
    22.  accept.bind(new InetSocketAddress(PORT));  
    23.           
    24.         System.out.println("upload  server started.");   
    25.  }  
    26. }  
     
     
    就这样简单的完成了服务端的实现,其实可以复杂一些,其中的log跟code都可以根据需要自己来写和生成,这里只使用mina自带的。
    然后是服务端的handler。
     
    Java代码  收藏代码
    1. import java.io.BufferedOutputStream;  
    2. import java.io.File;  
    3. import java.io.FileOutputStream;  
    4. import org.apache.commons.logging.Log;  
    5. import org.apache.commons.logging.LogFactory;  
    6. import org.apache.mina.core.service.IoHandlerAdapter;  
    7. import org.apache.mina.core.session.IoSession;  
    8.   
    9. public class FileUploadHandler extends IoHandlerAdapter {  
    10.   
    11.  private BufferedOutputStream out;  
    12.   
    13.  private int count;  
    14.   
    15.  private String fileName = "D:/log/test.jpg";  
    16.   
    17.  private static final Log log = LogFactory.getLog(FileUploadHandler.class);  
    18.   
    19.   
    20.  public void sessionOpened(IoSession session) throws Exception {  
    21.  System.out.println("server open");  
    22.  }  
    23.   
    24.  public void exceptionCaught(IoSession session, Throwable cause)  
    25.  throws Exception {  
    26.  System.out.println("exception");  
    27.  session.close(true);  
    28.  super.exceptionCaught(session, cause);  
    29.  }  
    30.   
    31.  public void messageReceived(IoSession session, Object message) {  
    32.  System.out.println("server received");  
    33.   
    34.  try {  
    35.  if (message instanceof FileUploadRequest) {  
    36.                  //FileUploadRequest 为传递过程中使用的DO。  
    37.  FileUploadRequest request = (FileUploadRequest) message;  
    38.  System.out.println(request.getFilename());  
    39.  if (out == null) {  
    40.  //新建一个文件输入对象BufferedOutputStream,随便定义新文件的位置  
    41.  out = new BufferedOutputStream(new FileOutputStream(  
    42.  "D:/log/" + request.getFilename()));  
    43.  out.write(request.getFileContent());  
    44.  } else {  
    45.  out.write(request.getFileContent());  
    46.  }  
    47.  count += request.getFileContent().length;  
    48.   
    49.  } else if (message instanceof String) {  
    50.  if (((String)message).equals("finish")) {  
    51.  System.out.println("size is"+count);  
    52.  //这里是进行文件传输后,要进行flush和close否则传递的文件不完整。  
    53.  out.flush();  
    54.  out.close();  
    55.  //回执客户端信息,上传文件成功  
    56.  session.write("success");  
    57.  }  
    58.  }  
    59.   
    60.  } catch (Exception e) {  
    61.  e.printStackTrace();  
    62.  }  
    63.  }  
    64.   
    65.  public void sessionClosed(IoSession session) throws Exception {  
    66.  System.out.println("server session close");  
    67.  }  
    68. }  
     
     
    所有的handler都要继承IoHandlerAdapter,可以查看IoHandlerAdapter,其包括几个关于session状态的方法。按需进行重载即可。
     
    然后就是公用的用来传输的DO:FileUploadRequest简单的POJO
     
    Java代码  收藏代码
    1. import java.io.Serializable;  
    2.   
    3. public class FileUploadRequest implements Serializable {  
    4.  private String hostname;  
    5.  private String filename;  
    6.  private byte[] fileContent;  
    7.   
    8.  public String getHostname() {  
    9.  return hostname;  
    10.  }  
    11.   
    12.  public void setHostname(String hostname) {  
    13.  this.hostname = hostname;  
    14.  }  
    15.   
    16.  public String getFilename() {  
    17.  return filename;  
    18.  }  
    19.   
    20.  public void setFilename(String filename) {  
    21.  this.filename = filename;  
    22.  }  
    23.   
    24.  public byte[] getFileContent() {  
    25.  return fileContent;  
    26.  }  
    27.   
    28.  public void setFileContent(byte[] fileContent) {  
    29.  this.fileContent = fileContent;  
    30.  }  
    31. }  
     
     
    接下来看下客户端的实现,也很简单:
     
    Java代码  收藏代码
    1. import java.io.File;  
    2. import java.io.FileInputStream;  
    3. import java.io.IOException;  
    4. import java.net.InetSocketAddress;  
    5. import nio.upload.server.FileUploadRequest;  
    6. import org.apache.mina.core.future.ConnectFuture;  
    7. import org.apache.mina.core.session.IoSession;  
    8. import org.apache.mina.filter.codec.ProtocolCodecFilter;  
    9. import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;  
    10. import org.apache.mina.filter.logging.LoggingFilter;  
    11. import org.apache.mina.transport.socket.nio.NioSocketConnector;  
    12.   
    13. public class MainClient {  
    14.   
    15.  private static final int PORT = 8080;  
    16.   
    17.  /** 
    18.   * @param args 
    19.   * @throws IOException 
    20.   */  
    21.  public static void main(String[] args) throws Exception {  
    22.  //客户端的实现  
    23.  NioSocketConnector connector = new NioSocketConnector();  
    24.  connector.getFilterChain().addLast("codec",  
    25.  new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));  
    26.  connector.getFilterChain().addLast("logging", new LoggingFilter());  
    27.  FileUploadClientHandler h = new FileUploadClientHandler();  
    28.  connector.setHandler(h);  
    29.  //本句需要加上,否则无法调用下面的readFuture来从session中读取到服务端返回的信息。  
    30.  connector.getSessionConfig().setUseReadOperation(true);  
    31.   
    32.  ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",  
    33.  PORT));  
    34.   
    35.  IoSession session;  
    36.  //等待连接成功  
    37.  cf.awaitUninterruptibly();  
    38.  session = cf.getSession();  
    39.   
    40.  System.out.println("client send begin");  
    41.    
    42.  //传递文件开始  
    43.  String fileName = "test.jpg";  
    44.  FileInputStream fis = new FileInputStream(new File(fileName));  
    45.  byte[] a = new byte[1024 * 4];  
    46.  FileUploadRequest request = new FileUploadRequest();  
    47.  request.setFilename(fileName);  
    48.  request.setHostname("localhost");  
    49.  while (fis.read(a, 0, a.length) != -1) {  
    50.  request.setFileContent(a);  
    51.  //像session中写入信息供服务端获得  
    52.  session.write(request);  
    53.  }  
    54.  //发送完成的标志  
    55.  session.write(new String("finish"));  
    56.   
    57.  System.out.println("client send finished and wait success");  
    58.  //接上面来取得服务端的信息  
    59.  Object result = session.read().awaitUninterruptibly().getMessage();  
    60.  if (result.equals("success")) {  
    61.  System.out.println("success!");  
    62.  //关闭客户端  
    63.  connector.dispose();  
    64.  }  
    65.  }  
    66. }  
     
     
    客户端handler的实现。
     
    Java代码  收藏代码
    1. import org.apache.mina.core.service.IoHandlerAdapter;  
    2. import org.apache.mina.core.session.IoSession;  
    3.   
    4.   
    5. public class FileUploadClientHandler extends IoHandlerAdapter {  
    6.   
    7.  public void sessionOpened(IoSession session) throws Exception {  
    8.  System.out.println("client open");  
    9.  }  
    10.   
    11.  public void sessionClosed(IoSession session) throws Exception {  
    12.  System.out.println("client session close");  
    13.  }  
    14.   
    15.  public void messageReceived(IoSession session, Object message)  
    16.  throws Exception {  
    17.  System.out.println("thr result is" + message);  
    18.  }  
  • 相关阅读:
    Lambda表达式、依赖倒置
    ASP.NET vNext 概述
    Uname
    RHEL4 i386下安装rdesktop【原创】
    Taxonomy of class loader problems encountered when using Jakarta Commons Logging(转)
    How to decompile class file in Java and Eclipse
    先有的资源,能看的速度看,不能看的,抽时间看。说不定那天就真的打不开了(转)
    Google App Engine 学习和实践
    【VBA研究】VBA通过HTTP协议实现邮件轨迹跟踪查询
    js正則表達式语法
  • 原文地址:https://www.cnblogs.com/weipeng/p/4042917.html
Copyright © 2011-2022 走看看