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.  }  
  • 相关阅读:
    GitHub 源码,Framework 框架
    转int啥啥啥的
    查看apk签名 和 keystore 的信息
    一次apk打开时报内存溢出错误,故写下内存溢出的各种原因和解决方法
    客户端传值里面包含URL特殊字符的应对方法
    Linux全硬盘搜索文件名是xxxxx的命令
    pythonmysql运行报错解决过程中遇到的其中一个报错解决文章来源
    linux查看硬盘占用情况
    Linux使用nginx反向代理。可实现域名指向特定端口
    Linux下使用yum安装软件命令
  • 原文地址:https://www.cnblogs.com/weipeng/p/4042917.html
Copyright © 2011-2022 走看看