利用MINA传送对象,字符串(前后台代码)

来源:互联网 发布:手机音量增大软件 编辑:程序博客网 时间:2024/06/05 16:04
http://lanxin1985.iteye.com/blog/493932

其中用到的第三方JAR包有两个,分别是mina-core-2.0.0-M5.jar和slf4j-nop-1.5.6.jar

NIO的优点。何时才使用。当你需要比较多的并发,而且并发的需要做长连接时,传统的连续池可能会满足不了你的需求,必竟如果连接池维护过多的连接时,对于虚拟机的要求比较高,但如果过少连接的话,阻塞的线程会让程序处理的非常慢,这时,你就可以考虑一下使用NIO框架MINA

下面是一个类似于HELLO WORLD的程序,相信熟悉SOCKET,看了马上就能上手MINA了。
客户端代码:


import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

public class MinaClient
{

private static int PORT=8991;
    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException
    {
        System.out.println("开始机器连续服务器");
        //创建TCP/IP的连接
        NioSocketConnector connector=new NioSocketConnector();
        //创建接收数据的过滤器
        DefaultIoFilterChainBuilder chain=connector.getFilterChain();
        /*
         * 这里注意点:
         * 1:TextLineCodecFactory设置这个过滤器一行一行(/r/n)的发送/读取数据
         * 2.ObjectSerializationCodecFactory一般发送/接收的是对象等形象,以对象形式读取
         */
        //chain.addLast("myChain",new ProtocolCodecFilter(new TextLineCodecFactory()));      
        chain.addLast("myChain",new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
        Message msg=new Message("TObject");
        //设置处理的类
        connector.setHandler(new MinaClientClient(msg));
   //设置时间
        connector.setConnectTimeoutMillis(300000);
   //开始连接服务器
   ConnectFuture cf=connector.connect(new InetSocketAddress("localhost",PORT));
   //等待连接结束
        cf.awaitUninterruptibly();
        cf.getSession().getCloseFuture().awaitUninterruptibly();   
        connector.dispose();   
       
    }

}

客户端用MinaClientClient来处理发送的信息,MinaClientClient类必须继承IoHandlerAdapter,类似于Struts中处理action的类必须继承Action


import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

public class MinaClientClient extends IoHandlerAdapter
{

    public MinaClientClient()
    {
    }
   
    private Object msg;
    public MinaClientClient(Object message)
    {
    this.msg=message;
    }
   
   
    @Override
    public void sessionOpened(IoSession session) throws Exception
    {
        System.out.println("我来了..");
        session.write(msg);
       
    }
   
    @Override
    public void sessionClosed(IoSession arg0) throws Exception
    {
        System.out.println("我走喽");
    }
   
    @Override
    public void messageReceived(IoSession session, Object message) throws Exception
    {
    Message msg=(Message)message;
    System.out.println("处理完的结果为"+msg.getMsgBody());
   
    }
   
    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
    //session.write(strC);
    // TODO Auto-generated method stub
    //super.messageSent(session, message);
    }
   
    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
       throws Exception {
    cause.printStackTrace();
    session.close(true);
    }
   
}

服务端代码:

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.core.filterchain.DefaultIoFilterChain;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class MainServer
{
    //设置端口
    public static int PORT=8991;
   
    /**
     * @param args
     * @throws IOException
     * @author jqh
     */
    public static void main(String[] args) throws IOException
    {
    System.out.println("服务创建中");
        //创建一个非阻塞的的server端socket,用NIO  
        SocketAcceptor acceptor=new NioSocketAcceptor();
       
        //创建接收数据的过滤器
        DefaultIoFilterChainBuilder chain=acceptor.getFilterChain();
       
        /*
         * 这里注意点:
         * 1:TextLineCodecFactory设置这个过滤器一行一行(/r/n)的读取数据
         * 2.ObjectSerializationCodecFactory一般接收的是对象等形象,以对象形式读取
         */
        //chain.addLast("chain", new ProtocolCodecFilter(new TextLineCodecFactory()));
        chain.addLast("chain", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
        //设定服务器端消息处理器.:就是我们创建的TimeServerHandler对象
        acceptor.setHandler(new TimeServerHandler());
       
        acceptor.bind(new InetSocketAddress(PORT));
       
        System.out.println("MINS 服务器监听的服务端口为"+PORT);
       
    }

}

类似于客户端,用于处理客户端请求的类为TimeServerHandler

import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;

import com.dzkj.socketserver.minaclient.Message;

public class TimeServerHandler extends IoHandlerAdapter
{
    /****
     * session打开时,调用
     */
    @Override
    public void sessionOpened(IoSession session) throws Exception
    {
        System.out.println("incoming client ..."+session.getRemoteAddress());
       
    }
    /***
     * 连接关才时调用
     */
    @Override
    public void sessionClosed(IoSession session) throws Exception
    {
        System.out.println("client close...........");
    }
    /**
     * 如果出异常,就关闭session
     */
    @Override
    public void exceptionCaught( IoSession session, Throwable cause ) throws Exception
    {
        cause.printStackTrace();
        session.close(true);
    }
   
    /**
     * 收到客户端信息时调用
     */
    @Override
    public void messageReceived( IoSession session, Object message ) throws Exception
    {
    System.out.println("in messageReceived");        
        Message msg = (Message) message;
        System.out.println("begin send msg: " + msg.getMsgBody());
        msg.setMsgBody("change it "+msg.getMsgBody());
        session.write(msg);
        System.out.println("Message written...");
    }
    /***
     * 空闲时调用
     */
    @Override
    public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
    {
        System.out.println( "IDLE " + session.getIdleCount( status ));
    }
}


对象类:

import java.io.Serializable;

public class Message implements Serializable {

    private String msgBody;
   
    public Message(String msgBody)
    {
        this.msgBody = msgBody;
    }

    public String getMsgBody() {
        return msgBody;
    }

    public void setMsgBody(String msgBody) {
        this.msgBody = msgBody;
    }
}

先运行服务器---

再运行客户端.可得到结果:

客户端控制台:
开始机器连续服务器
我来了..
处理完的结果为change it TObject
我走喽

服务端控制台:
服务创建中
MINS 服务器监听的服务端口为8991
incoming client .../127.0.0.1:4685
in messageReceived
begin send msg: TObject
Message written...
client close...........

当然,服务端会一直监听8991端口。有客户端请求就会做处理,还有发送String对象就不写详细代码了。主要区别就是上面注释提到的部分要改一下,然后直接写String过去即可。
还有要注意的是,传送Object时,对象一定要实现Serializable。反序例化一般比较严谨的操作。别忘了

0 0