Mina入门实例(一)
mina现在用的很多了,之前也有用到,但是毕竟不熟悉,于是查了一些资料,做了一些总结。看代码是最直观的,比什么长篇大论都要好。不过其中重要的理论,也要理解下。
首先是环境,程序运行需要几个包,这里用maven比较方便。
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>MyMinaServer</groupId>
<artifactId>mina</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>mina</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.0.4</version>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.6.1</version>
</dependency> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
然后就可以写代码了。
---------------------------------------------------------- 分割线 -----------------------------------------------------------------------------------------
一,简单的客户端和服务端程序
服务端程序:
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");
} }
这里的每个方法,算是事件。在每个事件中,我们可以定义自己的处理。在前面的《AndroidPn源码分析(一)》这篇文章中,笔者曾写过他们的每个事件代表的含义,不过从字面意思也很好理解。
这里主要是对接受到信息的处理,如果不是收到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,打印比较多信息。
到此,这个例子就完成了。
Mina入门实例(一)的更多相关文章
- Apache Mina入门实例
一.mina是啥 ApacheMINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可扩展性的网络应用程序.它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的 ...
- Apache Mina 入门实例
这个教程是介绍使用Mina搭建基础示例.这个教程内容是以创建一个时间服务器. 以下是这个教程需要准备的东西: MINA 2.0.7 Core JDK 1.5 或更高 SLF4J 1.3.0 或更高 L ...
- Mina入门实例
继续上一篇,这篇主要讲通过mina往B端发送消息.并接受消息,mina是一个网络通信框架,封装了javaNIO.简单易用.网上有非常多关于他的介绍,在此不赘述了. 如上篇所介绍,完毕功能,须要五个类: ...
- JAVA通信系列二:mina入门总结
一.学习资料 Mina入门实例(一) http://www.cnblogs.com/juepei/p/3939119.html Mina入门教程(二)----Spring4 集成Mina http:/ ...
- React 入门实例教程(转载)
本人转载自: React 入门实例教程
- struts入门实例
入门实例 1 .下载struts-2.3.16.3-all .不摆了.看哈就会下载了. 2 . 解压 后 找到 apps 文件夹. 3. 打开后将 struts2-blank.war ...
- Vue.js2.0从入门到放弃---入门实例
最近,vue.js越来越火.在这样的大浪潮下,我也开始进入vue的学习行列中,在网上也搜了很多教程,按着教程来做,也总会出现这样那样的问题(坑啊,由于网上那些教程都是Vue.js 1.x版本的,现在用 ...
- wxPython中文教程入门实例
这篇文章主要为大家分享下python编程中有关wxPython的中文教程,分享一些wxPython入门实例,有需要的朋友参考下 wxPython中文教程入门实例 wx.Window 是一个基类 ...
- Omnet++ 4.0 入门实例教程
http://blog.sina.com.cn/s/blog_8a2bb17d01018npf.html 在网上找到的一个讲解omnet++的实例, 是4.0下面实现的. 我在4.2上试了试,可以用. ...
随机推荐
- Python 判断字符串是否为数字
转载: http://www.runoob.com/python3/python3-check-is-number.html 以下实例通过创建自定义函数 is_number() 方法来判断字符串是否为 ...
- IIS与Apache共用80端口
Windows server 2003服务器上安装有默认 IIS 6和Apache两个服务器,IIS运行的一个.net程序,apache运行php程序,现在想让它们同时都能通过80端口访问,设置起来还 ...
- 迭代器模式/iterator模式/对象行为型模式
意图 又名:游标(Cursor): 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 动机 一个聚合对象,提供访问元素的方法,而有不暴露它的内部结构.如list,将对列表的访问 ...
- VadRoot枚举进程模块在Windows7下的完整实现
原理小伟的小伟在http://bbs.pediy.com/showthread.php?t=66886说的挺清楚了,Windows7下有一些变化,使用NtQueryVirtualMemory来枚举 ...
- NoSQL 数据库分类
类型 部分代表 特点 列存储 Hbase Cassandra Hypertable 顾名思义,是按列存储数据的.最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有 ...
- iOS APP可执行文件的组成
iOS APP编译后,除了一些资源文件,剩下的就是一个可执行文件,有时候项目大了,引入的库多了,可执行文件很大,想知道这个可执行文件的构成是怎样,里面的内容都是些什么,哪些库占用空间较高,可以用以下方 ...
- python+Eclipse+pydev环境搭建
python+Eclipse+pydev环境搭建 本文重点介绍使用Eclipse+pydev插件来写Python代码, 以及在Mac上配置Eclipse+Pydev 和Windows配置Ecli ...
- 配置gradle.properties
在一些项目中会分拆app 和 lib , 这时候引用support的时候,一旦更改版本会出现需要同步更改两个地方的问题.这种情况,可以通过配置gradle.properties实现替换. 在项目编译过 ...
- 数据库访问性能优化 Oracle
特别说明: 1. 本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2. 本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也 ...
- java 通过jdbc连接MySQL数据库
先了解下JDBC的常用接口 1.驱动程序接口Driver 每种数据库的驱动程序都应该提供一个实现java.sql.Driver接口的类,简称Driver类.通常情况下,通过java.lang.Clas ...