mina 框架java服务端的搭建和通信

创建java项目,导入mina包。mina下载地址:http://mina.apache.org/

不会用mina的请各种百度谷歌吧。。

新建MainServer.java类,继承于Thread并实现main函数。

然后就在MainServer类里搭建main结构啦。


类如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import  handler.MainHandler;
 
import  java.net.InetSocketAddress;
 
import  org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import  org.apache.mina.filter.codec.ProtocolCodecFilter;
import  org.apache.mina.transport.socket.nio.NioSocketAcceptor;
 
import  coder.buffer.BufferCoderFactory;
 
/**
  * @author duwei
  * @since 2013.10.25
 
  • The main thread of mina server 
  •   * */
    public  class  MainServer   extends  Thread{
         //the mina info
         public  boolean  isAlive =  true ;
         public  MainHandler handler;
         public  NioSocketAcceptor socketAcceptor;
         public  final  int  port =  8005 ;
         //database info
         public  static  String dbHost= "192.168.1.103" ,dbName= "test" ,username= "work" ,password= "123456" ;
         public  static  int  dbPort =  3306 ;
         
         public  MainServer(){
             super ( "MainServer" );
             socketAcceptor =  new  NioSocketAcceptor();
             socketAcceptor.setReuseAddress( true );
             socketAcceptor.getSessionConfig().setKeepAlive( true );
             handler =  new  MainHandler();
             socketAcceptor.setHandler(handler);
             //设置过滤器
             DefaultIoFilterChainBuilder chain = socketAcceptor.getFilterChain();
             chain.addLast( "codec" new  ProtocolCodecFilter( new  BufferCoderFactory())); //明码字符串
             //启动数据库
             startDataBaseDriver(dbHost, dbPort, dbName, username, password);
         }
         
         public  void  run(){
             while (isAlive){
                 try  {
                     sleep( 3000 );
                 catch  (Exception e) {
                     // TODO: handle exception
                 }
             }
             System.exit( 0 );
         }
         
         private  void  startDataBaseDriver(String host, int  port,String dbName,String username,String password){
             try  {
                 
             catch  (Exception e) {
                 e.printStackTrace();
             }
         }
         
         public  void  startAcceptor(){
             try  {
                 socketAcceptor.bind( new  InetSocketAddress(port));
                 this .start();
             catch  (Exception e) {
                 e.printStackTrace();
             }
         }
         
         /**
          * @param args
          */
         public  static  void  main(String[] args) {
             //start mina and database
             MainServer main =  new  MainServer();
             main.startAcceptor();
             System.out.println( "server started finished @ 192.168.1.122:8005" );
         }
     
    }

    从上述代码中可见,需要建立一个编解码工厂和一个实现IOHandler接口的实例啦,因为IOHandler接口是负责处理所有业务逻辑的啦。

    1. 所谓编解码工厂,就是一个负责在发送数据的最后阶段和接收数据的最开始阶段处理所发送和接收的数据。

    比如:服务端发送一段数据是:“数据长度(4字节)+实际数据”,那么接收到数据后就会首先读取4个字节的长度信息验证后面的实际数据有木有这么多。完了再从IoBuffer里解析出来写入ProtocolDecoderOutput里。发送数据也是类似,在session.write("...");发送数据后,会进入ProtocolEncoder实例里对数据经行封装。比如说加密,加压等操作。

    java代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package  coder.buffer;
     
    import  org.apache.mina.core.session.IoSession;
    import  org.apache.mina.filter.codec.ProtocolCodecFactory;
    import  org.apache.mina.filter.codec.ProtocolDecoder;
    import  org.apache.mina.filter.codec.ProtocolEncoder;
     
    public  class  BufferCoderFactory  implements  ProtocolCodecFactory {
         private  ProtocolEncoder encoder;
         private  ProtocolDecoder decoder;
         @Override
         public  ProtocolDecoder getDecoder(IoSession arg0)  throws  Exception {
             // TODO Auto-generated method stub
             decoder =  new  BufferDecoder();
             return  decoder;
         }
     
         @Override
         public  ProtocolEncoder getEncoder(IoSession arg0)  throws  Exception {
             // TODO Auto-generated method stub
             encoder =  new  BufferEncoder();
             return  encoder;
         }
    }

    编码类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    package  coder.buffer;
     
    import  java.io.ByteArrayOutputStream;
    import  java.io.IOException;
    import  java.util.zip.Deflater;
     
    import  org.apache.mina.core.buffer.IoBuffer;
    import  org.apache.mina.core.session.AttributeKey;
    import  org.apache.mina.core.session.IoSession;
    import  org.apache.mina.filter.codec.ProtocolEncoder;
    import  org.apache.mina.filter.codec.ProtocolEncoderOutput;
     
    public  class  BufferEncoder  implements  ProtocolEncoder{
          private  final  AttributeKey DEFLATER =  new  AttributeKey(getClass(),  "deflater" ); 
          private  static  int  buffersize =  1024 ;
          public  void  encode(IoSession session, Object in, ProtocolEncoderOutput out)
             throws  Exception{
             if (in  instanceof  String){
                 byte [] bytes = ((String) in).getBytes( "utf-8" );
                 System.out.println( "压缩前:" +bytes.length);
                 bytes = compress(session, bytes);
                 System.out.println( "压缩后:" +bytes.length);
                 IoBuffer buffer = IoBuffer.allocate(bytes.length +  4 );
                 buffer.putInt(bytes.length);
                 buffer.put(bytes);
                 buffer.flip();
                 session.write(buffer);
                 buffer.free();
             } else {
                 System.out.println( "message is not a String instance." );
             }
         }
         private  byte [] compress(IoSession session, byte [] inputs){
             Deflater deflater = (Deflater)session.getAttribute(DEFLATER);
            if (deflater ==  null ){
                deflater =  new  Deflater();
                session.setAttribute(DEFLATER,deflater);
            }
            deflater.reset();
            deflater.setInput(inputs);
            deflater.finish();
            byte [] outputs =  new  byte [ 0 ]; 
            ByteArrayOutputStream stream =  new  ByteArrayOutputStream(inputs.length); 
            byte [] bytes =  new  byte [buffersize];
            int  value; 
            while (!deflater.finished()){
                value = deflater.deflate(bytes);
                 stream.write(bytes, 0 , value);   
            }
            outputs = stream.toByteArray();
            try  {
                stream.close();
            catch  (IOException e) {
                e.printStackTrace();
            }
            return  outputs;
         }
         
        public  void  dispose(IoSession paramIoSession)
                     throws  Exception{
            
        }
    }

    解码类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    package  coder.buffer;
     
    import  org.apache.mina.core.buffer.IoBuffer;
    import  org.apache.mina.core.session.IoSession;
    import  org.apache.mina.filter.codec.ProtocolDecoder;
    import  org.apache.mina.filter.codec.ProtocolDecoderOutput;
     
    public  class  BufferDecoder  implements  ProtocolDecoder{
         
         public  static  final  int  MAX_MSG_SIZE =  5000 ;
         
         public  void  decode(IoSession paramIoSession, IoBuffer in, ProtocolDecoderOutput out)
                 throws  Exception{
             if  (in.prefixedDataAvailable( 4 , MAX_MSG_SIZE)) {
                 int  length = in.getInt();
                 byte [] bytes =  new  byte [length];
                 in.get(bytes);
                 out.write(bytes);
             else  {
     
             }
         }
     
         @Override
         public  void  dispose(IoSession arg0)  throws  Exception {
             // TODO Auto-generated method stub
             
         }
     
         @Override
         public  void  finishDecode(IoSession arg0, ProtocolDecoderOutput arg1)
                 throws  Exception {
             // TODO Auto-generated method stub
             
         }
    }


    2.编码完成后,数据就会交给IOHandler来处理啦,这里可以选择继承IoHandlerAdapter类来写。。

    IOHandler接口的几个重要方法介绍:

    sessionCreated:一个连接被创建时触发;

    sessionOpened:一个连接被打开时触发;

    sessionClosed:一个连接被关闭时触发;

    exceptionCaught:连接出现异常未被捕获时触发;

    messageReceived:连接收到消息时触发。

    好了,接下来实现自己的Handler实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    package  handler;
     
    import  org.apache.mina.core.service.IoHandlerAdapter;
    import  org.apache.mina.core.session.IoSession;
     
    public  class  MainHandler  extends  IoHandlerAdapter{
         public  void  sessionOpened(IoSession session)  throws  Exception {
             System.out.println( "session opened " +session.getRemoteAddress().toString());
         }
         public  void  messageReceived(IoSession session, Object message)  throws  Exception{
             String str =  new  String(( byte []) message,  "utf8" );
             //收到客户端发来的数据
             System.out.println( "received message: " +str);
             //向客户端发送数据
             session.write( "fuck you too." );
         }
         public  void  sessionClosed(IoSession session)  throws  Exception {
             System.out.println( "session closed " +session.getRemoteAddress().toString());
         }
         public  void  exceptionCaught(IoSession session, Throwable cause)
                 throws  Exception {
             System.out.println( "exceptionCaught" );
             cause.printStackTrace();
         }
    }

    好了,目前这个没有连接数据库的mina服务端就算是勉强搭建好了,运行一下试试??

    和你的客户端勾兑一下,看看有木有勾搭上~~ 哈哈~~

    本人新手,也不太熟悉java服务端。。

    如果有什么问题,么见怪哈。大家一起探讨,一起研究,一起进步。~~


    你可能感兴趣的:(网络编程)