开发环境:
System:Windows
JavaSDK:1.6
IDE:eclipse、MyEclipse 6.6
开发依赖库:
Jdk1.4+、mina-core-2.0.4.jar、slf4j-api-1.5.11.jar、slf4j-log4j12-1.5.11.jar
Email:hoojo_@126.com
前不久用Socket写的聊天程序,主要是手机端程序通过Socket连接服务器端的ServerSocket,然后服务器端根据客户端发送过来统一规范的报文。进行解析再用smack框架转发到openfire服务器,最后由openfire服务器向客户端程序发送聊天信息。
最近发现socket服务器资源消耗比较大。我是采用阻塞式多线程通信方式,这种方式会造成大量的服务器资源浪费、长期的占用服务器的CUP调度权,并且会长时间阻塞程序,等待客户端连接、发送消息等。
为了解决上面的状况,Apache MiNa能很好的解决这个问题。Mina采用的是非阻塞式、单线程、NIO通信方式。
非阻塞式通信的思想是:让一个线程同时完成多件事,这个线程会利用完成这件事的空余时间去完成另一件事,一刻也不闲着。这个线程同时也会不断监控每件事情中需要处理时间的发生,发生一个就处理一件,然后继续监听各自事情。
一、介绍
首先,Mina是个什么东西?看下官方网站(http://mina.apache.org/)对它的解释:
Apache的Mina(Multipurpose Infrastructure Networked Applications)是一个网络应用框架,可以帮助用户开发高性能和高扩展性的网络应用程序;它提供了一个抽象的、事件驱动的异步API,使Java NIO在各种传输协议(如TCP/IP,UDP/IP协议等)下快速高效开发。
Apache Mina也称为:
NIO框架
网络套接字(networking socket)类库
事件驱动的异步API(注意:在JDK7中也新增了异步API)
总之:我们简单理解它是一个封装底层IO操作,提供高级操作API的通讯框架!
二、服务器端编码工作
第一步:
使用Apache MiNa框架,你需要下载jar
下载地址:http://mina.apache.org/dyn/closer.cgi/mina/2.0.4/apache-mina-2.0.4-bin.zip
你需要添加jar如下
如果你使用日志,需要添加日志配置文件log4j.properties
第二步:
编写通信要用的解码工厂和编码器、解码器类,代码如下
package com.hoo.mina.code.factory;
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;
import com.hoo.mina.code.CharsetDecoder;
import com.hoo.mina.code.CharsetEncoder;
/**
* <b>function:</b> 字符编码、解码工厂类,编码过滤工厂
* @author hoojo
* @createDate 2012-6-26 下午01:08:50
* @file CharsetCodecFactory.java
* @package com.hoo.mina.code.factory
* @project ApacheMiNa
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class CharsetCodecFactory implements ProtocolCodecFactory {@Overridepublic ProtocolDecoder getDecoder(IoSession session) throws Exception {return new CharsetDecoder();}@Overridepublic ProtocolEncoder getEncoder(IoSession session) throws Exception {return new CharsetEncoder();}}解码类
package com.hoo.mina.code;
import java.nio.charset.Charset;
import org.apache.log4j.Logger;
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;
/**
* <b>function:</b> 字符解码
* @author hoojo
* @createDate 2012-6-26 上午11:14:18
* @file CharsetDecoder.java
* @package com.hoo.mina.code
* @project ApacheMiNa
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class CharsetDecoder implements ProtocolDecoder {private final static Logger log = Logger.getLogger(CharsetDecoder.class);private final static Charset charset = Charset.forName("UTF-8");// 可变的IoBuffer数据缓冲区
private IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);
@Overridepublic void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {log.info("#########decode#########");
// 如果有消息
while (in.hasRemaining()) {
// 判断消息是否是结束符,不同平台的结束符也不一样;
// windows换行符(\r\n)就认为是一个完整消息的结束符了; UNIX 是\n;MAC 是\r
byte b = in.get();
if (b == '\n') {buff.flip();byte[] bytes = new byte[buff.limit()];buff.get(bytes);String message = new String(bytes, charset);
buff = IoBuffer.allocate(100).setAutoExpand(true);// 如果结束了,就写入转码后的数据
out.write(message);//log.info("message: " + message);
} else {
buff.put(b);}}}@Overridepublic void dispose(IoSession session) throws Exception {log.info("#########dispose#########");
log.info(session.getCurrentWriteMessage());}@Overridepublic void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {log.info("#########完成解码#########");
}}上面的decode方法是解码方法,它主要是把读取到数据中的换行符去掉。因为在mina通信协议中以换行符为结束符,如果不定义结束符那么程序会在那里一直等待下一条发送的数据。
这里用到了IoBuffer,MiNa中传输的所有二进制信息都存放在IoBuffer中,IoBuffer是对Java NIO中ByteBuffer的封装(Mina2.0以前版本这个接口也是ByteBuffer),提供了更多操作二进制数据,对象的方法,并且存储空间可以自增长,用起来非常方便;简单理解,它就是个可变长度的byte字节数组!
1. static IoBuffer allocate(int capacity,boolean useDirectBuffer)
创建IoBuffer实例,第一个参数指定初始化容量,第二个参数指定使用直接缓冲区还是JAVA 内存堆的缓存区,默认为false。
2.IoBuffer setAutoExpand(boolean autoExpand)
这个方法设置IoBuffer 为自动扩展容量,也就是前面所说的长度可变,那么可以看出长度可变这个特性默认是不开启的。
3. IoBuffer flip()
limit=position, position=0,重置mask,为了读取做好准备,一般是结束buffer操作,将buffer写入输出流时调用;这个必须要调用,否则极有可能position!=limit,导致position后面没有数据;每次写入数据到输出流时,必须确保position=limit。
4. IoBuffer clear()与IoBuffer reset()
clear:limit=capacity , position=0,重置mark;它是不清空数据,但从头开始存放数据做准备---相当于覆盖老数据。
reset就是清空数据
5. int remaining()与boolean hasRemaining()
这两个方法一般是在调用了flip方法后使用的,remaining()是返回limt-position的值!hasRemaining()则是判断当前是否有数据,返回position < limit的boolean值!
编码类
package com.hoo.mina.code;
import java.nio.charset.Charset;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.apache.mina.filter.codec.textline.LineDelimiter;
/**
* <b>function:</b> 字符编码
* @author hoojo
* @createDate 2012-6-26 上午11:32:05
* @file CharsetEncoder.java
* @package com.hoo.mina.code
* @project ApacheMiNa
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class CharsetEncoder implements ProtocolEncoder {private final static Logger log = Logger.getLogger(CharsetEncoder.class);private final static Charset charset = Charset.forName("UTF-8");@Overridepublic void dispose(IoSession session) throws Exception {log.info("#############dispose############");
}@Overridepublic void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {log.info("#############字符编码############");
IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);buff.putString(message.toString(), charset.newEncoder());// put 当前系统默认换行符
buff.putString(LineDelimiter.DEFAULT.getValue(), charset.newEncoder());// 为下一次读取数据做准备
buff.flip();out.write(buff);}}
第三步:
编写IoHandler实现类代码,IoHander这里是Io读写的事件驱动类,这里的Io操作都会触发里面的事件。你所有的业务逻辑都应当在这个类中完成。
package com.hoo.mina.server.message;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import org.apache.mina.core.future.CloseFuture;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <b>function:</b> 处理服务器端消息
* @author hoojo
* @createDate 2012-6-26 下午01:12:34
* @file ServerMessageHandler.java
* @package com.hoo.mina.server.message
* @project ApacheMiNa
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class ServerMessageHandler implements IoHandler {private final static Logger log = LoggerFactory.getLogger(ServerMessageHandler.class);@Overridepublic void exceptionCaught(IoSession session, Throwable cause) throws Exception {log.info("服务器发生异常: {}", cause.getMessage());
}@Overridepublic void messageReceived(IoSession session, Object message) throws Exception {log.info("服务器接收到数据: {}", message);
String content = message.toString();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");String datetime = sdf.format(new Date());
log.info("转发 messageReceived: " + datetime + "\t" + content);// 拿到所有的客户端Session
Collection<IoSession> sessions = session.getService().getManagedSessions().values();// 向所有客户端发送数据
for (IoSession sess : sessions) {
sess.write(datetime + "\t" + content);
}}@Overridepublic void messageSent(IoSession session, Object message) throws Exception {log.info("服务器发送消息: {}", message);
}@Overridepublic void sessionClosed(IoSession session) throws Exception {log.info("关闭当前session:{}#{}", session.getId(), session.getRemoteAddress());
CloseFuture closeFuture = session.close(true);closeFuture.addListener(new IoFutureListener<IoFuture>() {
public void operationComplete(IoFuture future) {if (future instanceof CloseFuture) {((CloseFuture) future).setClosed();log.info("sessionClosed CloseFuture setClosed-->{},", future.getSession().getId());
}}});}@Overridepublic void sessionCreated(IoSession session) throws Exception {log.info("创建一个新连接:{}", session.getRemoteAddress());
session.write("welcome to the chat room !");
}@Overridepublic void sessionIdle(IoSession session, IdleStatus status) throws Exception {log.info("当前连接{}处于空闲状态:{}", session.getRemoteAddress(), status);
}@Overridepublic void sessionOpened(IoSession session) throws Exception {log.info("打开一个session:{}#{}", session.getId(), session.getBothIdleCount());
}}sessionCreated:当一个新的连接建立时,由I/O processor thread调用;
sessionOpened:当连接打开是调用;
messageReceived: 当接收了一个消息时调用;
messageSent:当一个消息被(IoSession#write)发送出去后调用;
sessionIdle:当连接进入空闲状态时调用;
sessionClosed:当连接关闭时调用;
exceptionCaught:实现IoHandler的类抛出异常时调用;
一般情况下,我们最关心的只有messageReceived方法,接收消息并处理,然后调用IoSession的write方法发送出消息!(注意:这里接收到的消息都是Java对象,在IoFilter中所有二进制数据都被解码)一般情况下很少有人实现IoHandler接口,而是继承它的一个实现类IoHandlerAdapter,这样不用覆盖它的7个方法,只需要根据具体需求覆盖其中的几个方法就可以!
Iohandler的7个方法其实是根据session的4个状态值间变化来调用的:
Connected:会话被创建并使用;
Idle:会话在一段时间(可配置)内没有任何请求到达,进入空闲状态;
Closing:会话将被关闭(剩余message将被强制flush);
Closed:会话被关闭;
状态转换图如下:
第四步:
编写server启动类,bind端口、设置编码过程和核心业务处理器
package com.hoo.mina.server;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.SocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import com.hoo.mina.code.factory.CharsetCodecFactory;
import com.hoo.mina.server.message.ServerMessageHandler;
/**
* <b>function:</b> 服务器启动类
* @author hoojo
* @createDate 2012-6-29 下午07:11:00
* @file MinaServer.java
* @package com.hoo.mina.server
* @project ApacheMiNa
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class MinaServer {private SocketAcceptor acceptor;
public MinaServer() {
// 创建非阻塞的server端的Socket连接
acceptor = new NioSocketAcceptor();
}public boolean start() {DefaultIoFilterChainBuilder filterChain = acceptor.getFilterChain();// 添加编码过滤器 处理乱码、编码问题
filterChain.addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));/*LoggingFilter loggingFilter = new LoggingFilter();
loggingFilter.setMessageReceivedLogLevel(LogLevel.INFO);
loggingFilter.setMessageSentLogLevel(LogLevel.INFO);
// 添加日志过滤器
filterChain.addLast("loger", loggingFilter);*/
// 设置核心消息业务处理器
acceptor.setHandler(new ServerMessageHandler());
// 设置session配置,30秒内无操作进入空闲状态
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);try {
// 绑定端口3456
acceptor.bind(new InetSocketAddress(3456));
} catch (IOException e) {
e.printStackTrace();return false;
}return true;
}public static void main(String[] args) {MinaServer server = new MinaServer();
server.start();}}上面的代码主要完成启动参数的设置,如端口、session参数;消息核心业务处理器,这个比较关键,我们所有的业务都要在这里完成;然后就是日志、编码过滤器,我们可以对发送或接收到的消息进行处理、编码操作,在网络中传递数据都是字节流传递的,我们要获取消息必须把二进制的字节流转换的字符串来处理,所以这个也是必须的;同时你还可以对服务器添加日志过滤器,来显示日志。
这样服务器端程序就已经完成,你可以用socket或mina client等方式连接服务器,进行通信。
启动服务器,在浏览器中输入http://localhost:3456 这里的服务器绑定的端口是3456
然后你在控制台中可以看到当前浏览器的一些基本信息,如果你看到这些信息就表示你服务器代码编写没有什么问题,应该可以成功建立客户端连接。信息如下:
2012-08-01 09:55:56,046 INFO [com.hoo.mina.server.message.ServerMessageHandler:75-NioProcessor-1] - 创建一个新连接:/127.0.0.1:25422012-08-01 09:55:56,046 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-1] - #############字符编码############2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:86-NioProcessor-1] - 打开一个session:3#02012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:55-NioProcessor-1] - 服务器发送消息: welcome to the chat room !2012-08-01 09:55:56,062 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-1] - #########decode#########2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-1] - 服务器接收到数据: GET / HTTP/1.12012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-1] - 转发 messageReceived: 2012-08-01 09:55:56 GET / HTTP/1.12012-08-01 09:55:56,062 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-1] - #############字符编码############2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-1] - 服务器接收到数据: Host: localhost:34562012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-1] - 转发 messageReceived: 2012-08-01 09:55:56 Host: localhost:34562012-08-01 09:55:56,062 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-1] - #############字符编码############2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-1] - 服务器接收到数据: User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.12012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-1] - 转发 messageReceived: 2012-08-01 09:55:56 User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.12012-08-01 09:55:56,062 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-1] - #############字符编码############2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-1] - 服务器接收到数据: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-1] - 转发 messageReceived: 2012-08-01 09:55:56 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
其他内容省略……
三、客户端编码工作
第一步:
编写客户端消息核心处理业务类型,消息处理器
package com.hoo.mina.client.message;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <b>function:</b> 客户端消息处理类
* @author hoojo
* @createDate 2012-6-29 下午07:24:22
* @file ClientMessageHandlerAdapter.java
* @package com.hoo.mina.client.message
* @project ApacheMiNa
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class ClientMessageHandlerAdapter extends IoHandlerAdapter {private final static Logger log = LoggerFactory.getLogger(ClientMessageHandlerAdapter.class);public void messageReceived(IoSession session, Object message) throws Exception {String content = message.toString();log.info("client receive a message is : " + content);
}public void messageSent(IoSession session , Object message) throws Exception{log.info("messageSent 客户端发送消息:" + message);
}@Overridepublic void exceptionCaught(IoSession session, Throwable cause) throws Exception {log.info("服务器发生异常: {}", cause.getMessage());
}}这里我们没有实现IoHandler这个接口,而是继承了IoHandlerAdapter这类,覆盖了messageReceived、messageSent这两个方法。IoHandlerAdapter是IoHandler接口的一个实现,我们这里没有必要实现IoHandler的所有方法。
第二步:
编写连接服务器的代码,设置核心消息处理器
package com.hoo.mina.client;
import java.net.InetSocketAddress;
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.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import com.hoo.mina.client.message.ClientMessageHandlerAdapter;
import com.hoo.mina.code.factory.CharsetCodecFactory;
/**
* <b>function:</b> mina客户端
* @author hoojo
* @createDate 2012-6-29 下午07:28:45
* @file MinaClient.java
* @package com.hoo.mina.client.message
* @project ApacheMiNa
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class MinaClient {private SocketConnector connector;
private ConnectFuture future;
private IoSession session;
public boolean connect() {// 创建一个socket连接
connector = new NioSocketConnector();
// 设置链接超时时间
connector.setConnectTimeoutMillis(3000);// 获取过滤器链
DefaultIoFilterChainBuilder filterChain = connector.getFilterChain();// 添加编码过滤器 处理乱码、编码问题
filterChain.addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));/*
// 日志
LoggingFilter loggingFilter = new LoggingFilter();
loggingFilter.setMessageReceivedLogLevel(LogLevel.INFO);
loggingFilter.setMessageSentLogLevel(LogLevel.INFO);
filterChain.addLast("loger", loggingFilter);*/
// 消息核心处理器
connector.setHandler(new ClientMessageHandlerAdapter());
// 连接服务器,知道端口、地址
future = connector.connect(new InetSocketAddress(3456));
// 等待连接创建完成
future.awaitUninterruptibly();// 获取当前session
session = future.getSession();return true;
}public void setAttribute(Object key, Object value) {session.setAttribute(key, value);}public void send(String message) {session.write(message);}public boolean close() {CloseFuture future = session.getCloseFuture();future.awaitUninterruptibly(1000);connector.dispose();return true;
}public SocketConnector getConnector() {
return connector;
}public IoSession getSession() {
return session;
}}
第三步:
完成启动、在控制台输入你发送的内容
package com.hoo.mina.client.main;
import java.util.Scanner;
import com.hoo.mina.client.MinaClient;
/**
* <b>function:</b> 运行客户端程序
* @author hoojo
* @createDate 2012-6-29 下午07:36:44
* @file RunClient.java
* @package com.hoo.mina.client.main
* @project ApacheMiNa
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class RunClient {
public static void main(String[] args) {
MinaClient client = new MinaClient();
if (client.connect()) {
client.send("连接服务器成功!");
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
client.send(scanner.next());
}
}
}
}
启动服务器,运行客户端程序可以看到控制台:
2012-08-01 10:01:15,953 INFO [com.hoo.mina.code.CharsetEncoder:34-main] - #############字符编码############
2012-08-01 10:01:15,953 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:01:15,953 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:25-NioProcessor-2] - client receive a message is : welcome to the chat room !
2012-08-01 10:01:15,984 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:29-NioProcessor-2] - messageSent 客户端发送消息:连接服务器成功!
2012-08-01 10:01:15,984 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:01:15,984 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:25-NioProcessor-2] - client receive a message is : 2012-08-01 10:01:15
服务器控制台:
2012-08-01 10:01:15,921 INFO [com.hoo.mina.server.message.ServerMessageHandler:75-NioProcessor-2] - 创建一个新连接:/192.168.8.22:2644
2012-08-01 10:01:15,937 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-2] - #############字符编码############
2012-08-01 10:01:15,937 INFO [com.hoo.mina.server.message.ServerMessageHandler:86-NioProcessor-2] - 打开一个session:1#0
2012-08-01 10:01:15,937 INFO [com.hoo.mina.server.message.ServerMessageHandler:55-NioProcessor-2] - 服务器发送消息: welcome to the chat room !
2012-08-01 10:01:15,984 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:01:15,984 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-2] - 服务器接收到数据: 连接服务器成功!
2012-08-01 10:01:15,984 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-2] - 转发 messageReceived: 2012-08-01 10:01:15 连接服务器成功!
2012-08-01 10:01:15,984 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-2] - #############字符编码############
2012-08-01 10:01:15,984 INFO [com.hoo.mina.server.message.ServerMessageHandler:55-NioProcessor-2] - 服务器发送消息: 2012-08-01 10:01:15 连接服务器成功!
2012-08-01 10:01:45,984 INFO [com.hoo.mina.server.message.ServerMessageHandler:81-NioProcessor-2] - 当前连接/192.168.8.22:2644处于空闲状态:both idle
在客户端控制台输入聊天内容
hello,MiNaChat~!
2012-08-01 10:03:49,093 INFO [com.hoo.mina.code.CharsetEncoder:34-main] - #############字符编码############
2012-08-01 10:03:49,093 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:29-NioProcessor-2] - messageSent 客户端发送消息:hello,MiNaChat~!
2012-08-01 10:03:49,093 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:03:49,093 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:25-NioProcessor-2] - client receive a message is : 2012-08-01 10:03:49
服务器端接收到内容
2012-08-01 10:03:49,093 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:03:49,093 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-2] - 服务器接收到数据: hello,MiNaChat~!
2012-08-01 10:03:49,093 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-2] - 转发 messageReceived: 2012-08-01 10:03:49 hello,MiNaChat~!
2012-08-01 10:03:49,093 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-2] - #############字符编码############
2012-08-01 10:03:49,093 INFO [com.hoo.mina.server.message.ServerMessageHandler:55-NioProcessor-2] - 服务器发送消息: 2012-08-01 10:03:49 hello,MiNaChat~!
2012-08-01 10:04:19,093 INFO [com.hoo.mina.server.message.ServerMessageHandler:81-NioProcessor-2] - 当前连接/192.168.8.22:2644处于空闲状态:both idle
相关推荐
用Apache MiNa 实现多人聊天室,项目直接导进去myeclipse就可以运行了,懒人必备
mina实现多人聊天工程源码!先运行已打好的服务器jar,然后在吧swf文件丢到网页中,即可运行。工程源码齐全!
该程序集成mina框架与spring框架实现多人聊天程序
这是MINA实现的多人聊天的技术原型 采用MAVEN做配置管理, 项目需要jar里面也有,是从Maven的repository中拔下来的 供大家参考
Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)Apache Mina Server 2.0中文参考手册V1.0,Apache Mina2.0学习笔记(修订版)
基于Apache Mina实现的TCP长连接和短连接实例 详细说明,可参见blog http://blog.csdn.net/peterwanghao/article/details/6900523
深入理解Apache_Mina_(1)----_Mina的几个类 深入理解Apache_Mina_(2)----_与IoFilter相关的几个类 深入理解Apache_Mina_(3)----_与IoHandler相关的几个类 深入理解Apache_Mina_(4)----_IoFilter和IoHandler的区别和...
Apache MINA 线程模型配置 Mina配置
这个是我学的apache mina2.0学习笔记的实例
收集整理的Apache Mina chm pdf教程和帮助文档
Apache MINA是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架。 当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版...
Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序。 apache-mina-2.0.7-bin.zip,apache-mina-2.0.7-src.zip,log4j-1.2.17.zip,slf4j-api-1.6.6.jar,slf4j-api-1.6.6-...
apache mina的入门完整学习资料,附加中文参考手册。
apache mina 简单示例apache mina 简单示例apache mina 简单示例apache mina 简单示例apache mina 简单示例apache mina 简单示例
Apache MINA2实用手册 Apache MINA2实用手册
apache mina实例免费下载,有很多实例代码简单易懂欢迎大家下载!
一个Apache MINA使用案例源代码ApacheMina
Apache MINA 2.0 用户指南
apache mina chm 格式的api帮助文档。