博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mina入门实例(一)
阅读量:7198 次
发布时间:2019-06-29

本文共 9707 字,大约阅读时间需要 32 分钟。

mina现在用的很多了,之前也有用到,但是毕竟不熟悉,于是查了一些资料,做了一些总结。看代码是最直观的,比什么长篇大论都要好。不过其中重要的理论,也要理解下。

首先是环境,程序运行需要几个包,这里用maven比较方便。

pom.xml:

4.0.0
MyMinaServer
mina
0.0.1-SNAPSHOT
jar
mina
http://maven.apache.org
UTF-8
org.apache.mina
mina-core
2.0.4
org.slf4j
jcl-over-slf4j
1.6.1
org.slf4j
slf4j-nop
1.6.1
junit
junit
3.8.1
test

然后就可以写代码了。

---------------------------------------------------------- 分割线 -----------------------------------------------------------------------------------------

一,简单的客户端和服务端程序

服务端程序:

package MyMinaServer.mina;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.charset.Charset;import org.apache.mina.core.service.IoAcceptor;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.filter.codec.textline.TextLineCodecFactory;import org.apache.mina.filter.logging.LoggingFilter;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;public class MainServer {    private static final int Port=8888;    public static void main(String[] args) {        IoAcceptor ioAcceptor=new NioSocketAcceptor();        System.out.println("begin server....");        ioAcceptor.getFilterChain().addLast("logger", new LoggingFilter());        ioAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));        ioAcceptor.setHandler(new HelloWorldHandler());        ioAcceptor.getSessionConfig().setReadBufferSize(2048);        ioAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);        try {            ioAcceptor.bind(new InetSocketAddress(Port));        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

服务端,创建连接,然后这里注册了几个过滤链,这里简单写了需要的两个,到后面的内容中还可以加入一个加密的ssl链。

其中重要的是setHandler这个,在这个里面,我们可以定义自己的handler,然后做自己的业务。下面有这个handler的简单代码。

最后设置session的缓冲,和idle(空闲处理)的设定,再为此连接绑定一个端口。

其中需要注意的是,在服务端和客户端的代码里面,如果要传递string信息,codec编码过滤器中,要这么写:new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))。否则报错。

业务处理的handler:

package MyMinaServer.mina;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.session.IoSession;public class HelloWorldHandler extends IoHandlerAdapter{    @Override    public void exceptionCaught(IoSession session, Throwable cause)            throws Exception {        // TODO Auto-generated method stub        super.exceptionCaught(session, cause);    }    @Override    public void messageReceived(IoSession session, Object message)            throws Exception {        // TODO Auto-generated method stub        String string=message.toString();        if (string.trim().equalsIgnoreCase("quit")) {            session.close(true);            return;        }        System.out.println("recevied message:"+string);        String reply=" hi, i am server";        session.write(reply);        System.out.println("message have been written");    }    @Override    public void messageSent(IoSession session, Object message) throws Exception {        // TODO Auto-generated method stub        System.out.println("message have been sent");    }    @Override    public void sessionClosed(IoSession session) throws Exception {        // TODO Auto-generated method stub        System.out.println("closed session");    }    @Override    public void sessionCreated(IoSession session) throws Exception {        // TODO Auto-generated method stub        System.out.println("session created");    }    @Override    public void sessionIdle(IoSession session, IdleStatus status)            throws Exception {        // TODO Auto-generated method stub        System.out.println("IDLE "+session.getIdleCount(status));    }    @Override    public void sessionOpened(IoSession session) throws Exception {        // TODO Auto-generated method stub        System.out.println("session opened");    }}

这里的每个方法,算是事件。在每个事件中,我们可以定义自己的处理。在前面的《》这篇文章中,笔者曾写过他们的每个事件代表的含义,不过从字面意思也很好理解。

这里主要是对接受到信息的处理,如果不是收到quit字符,则返回给客户端一句 hi,i am server。

服务端暂时到此,以下是客户端。

package com.example.mina.server;import java.net.InetSocketAddress;import java.nio.charset.Charset;import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;import org.apache.mina.core.future.CloseFuture;import org.apache.mina.core.future.ConnectFuture;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.filter.codec.textline.TextLineCodecFactory;import org.apache.mina.filter.logging.LoggingFilter;import org.apache.mina.transport.socket.SocketConnector;import org.apache.mina.transport.socket.nio.NioSocketConnector;import com.example.mina.charset.CharsetFactory;import com.example.mina.hanlder.MsgHanler;public class MinaClient {    private SocketConnector connector;    private ConnectFuture future;    private IoSession session;    public boolean connect() {        /*         * 1.创建一个socket连接,连接到服务器         */        connector = new NioSocketConnector();        /*         * 获取过滤器链,用于添加过滤器         */        DefaultIoFilterChainBuilder chain = connector.getFilterChain();        // b.添加日志过滤器        chain.addLast("logger", new LoggingFilter());        // c.添加字符的编码过滤器        chain.addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));        /*         * 3.设置消息处理器,用于处理接收到的消息         */        connector.setHandler(new MsgHanler());        /*         * 4.根据IP和端口号连接到服务器         */        future = connector.connect(new InetSocketAddress("127.0.0.1", 8888));        // 等待连接创建完成        future.awaitUninterruptibly();        /*         * 5.获取session对象,通过session可以向服务器发送消息;         */        session = future.getSession();        session.getConfig().setUseReadOperation(true);        return future.isConnected();    }    /**     * 往服务器发送消息     *      * @param message     */    public void sendMsg2Server(String message) {        session.write(message);    }    /**     * 关闭与服务器的连接     *      * @return     */    public boolean close() {        CloseFuture future = session.getCloseFuture();        future.awaitUninterruptibly(1000);        connector.dispose();        return true;    }}

然后同样是一个客户端的handler,和server的很像:

package com.example.mina.hanlder;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class MsgHanler extends IoHandlerAdapter {    private static final Logger log = LoggerFactory.getLogger(MsgHanler.class);    @Override    public void exceptionCaught(IoSession session, Throwable cause)            throws Exception {        // 出现异常        log.error("--------exception--------");        super.exceptionCaught(session, cause);    }    @Override    public void messageReceived(IoSession session, Object message)            throws Exception {        // 从服务器中接收到消息后的处理        log.info("--------msg receive--------");        log.info("Message:{}" + message.toString());        super.messageReceived(session, message);    }    @Override    public void messageSent(IoSession session, Object message) throws Exception {        // 往服务器中发送消息        log.info("--------msg sent--------");        super.messageSent(session, message);    }    @Override    public void sessionCreated(IoSession session) throws Exception {        // 当session被创建的时候调用        log.info("--------session create--------");        super.sessionCreated(session);    }}

写一个入口方法:

package com.example.mina.server;public class Main {    public static void main(String[] args) {        MinaClient client=new MinaClient();        client.connect();        client.sendMsg2Server("message from cilent");    }}

这样,客户端就可以工作了。

先启动服务端,然后启动客户端,就可以看到在两个控制台中,分别有交互信息。

服务端:

begin server....

session created
session opened
recevied message:message from cilent
message have been written
message have been sent

客户端:

[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(186) | CREATED

[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.sessionCreated(54) | --------session create--------
[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(186) | OPENED
[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(157) | SENT: HeapBuffer[pos=0 lim=0 cap=0: empty]
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.messageSent(47) | --------msg sent--------
[QC] INFO [NioProcessor-2] org.apache.mina.filter.logging.LoggingFilter.log(157) | RECEIVED: HeapBuffer[pos=0 lim=17 cap=2048: 20 68 69 2C 20 69 20 61 6D 20 73 65 72 76 65 72...]
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.messageReceived(39) | --------msg receive--------
[QC] INFO [NioProcessor-2] com.example.mina.hanlder.MsgHanler.messageReceived(40) | Message:{} hi, i am server

客户端因为用了log4j,打印比较多信息。

到此,这个例子就完成了。

 

转载于:https://www.cnblogs.com/juepei/p/3939119.html

你可能感兴趣的文章
Timer定时器
查看>>
Win7、Ubuntu双系统正确卸载Ubuntu系统
查看>>
两数互换的例子
查看>>
我的友情链接
查看>>
网络拓扑自动发现-Sugarnms智能网管软件的基础
查看>>
线程的状态转换图
查看>>
VMware vSphere 5.0 五大改变
查看>>
spring注解性的事物@Transactional不起作用
查看>>
使用aulayout自适应uitableviewcell高度
查看>>
让我们一起Go(三)
查看>>
简单的Linux数据备份方案
查看>>
linux postgresql 安装配置详解
查看>>
一个监控tomcat运行的脚本分享
查看>>
电脑可以上网但网络连接显示感叹号
查看>>
我的友情链接
查看>>
MaxCompute用户初体验
查看>>
阿里云十年再出发,边缘计算已启航
查看>>
代理服务器与网络地址转换NAT
查看>>
我的友情链接
查看>>
SQL Server 镜像
查看>>