Apache MINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可靠性的网络应用程序。它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的事件驱动的异步API。

  Apache MINA 也称为:
  ● NIO 框架库
  ● 客户端服务器框架库
  ● 一个网络套接字库
  MINA虽然简单但是仍然提供了全功能的网络应用程序框架:
  ● 为不同的传输类型提供了统一的API:
  ○ 通过Java NIO提供TCP/IP 和 UDP/IP支持
  ○ 通过RXTX提供串口通讯(RS232)
  ○ In-VM管道通讯
  ○ 你能实现你自己的API!
  ● 过滤器作为一个扩展特性; 类似Servlet过滤器
  ● 低级和高级的API:
  ○ 低级: 使用字节缓存(ByteBuffers)
  ○ 高级: 使用用户定义的消息对象(objects)和编码(codecs)
  ● 高度定制化线程模型:
  ○ 单线程
  ○ 一个线程池
  ○ 一个以上的线程池(也就是SEDA)
  ● 使用Java 5 SSL引擎提供沙盒(Out-of-the-box) SSL · TLS · StartTLS支持
  ● 超载保护和传输流量控制
  ● 利用模拟对象进行单元测试
  ● JMX管理能力
  ● 通过StreamIoHandler提供基于流的I/O支持
  ● 和知名的容器(例如PicoContainer、Spring)集成
  ● 从Netty平滑的迁移到MINA, Netty是MINA的前辈。

MINA 基本类的描述 : 
IoAccepter 相当于网络应用程序中的服务器端 
IoConnector 相当于客户端 
IoSession 当前客户端到服务器端的一个连接实例 
IoHandler 业务处理逻辑 
IoFilter 过滤器用于悬接通讯层接口与业务层接口

要编写和运行一个基于Apache MINA 2.0的程序,需要JDK 5.0以上版本,

下面看一个domo:

准备工作:

mina-core-2.0.0-M6.jar
slf4j-api-1.5.2.jar

在官网下载到mina,找出这几个jar,添加到项目,

服务端的代码:

  1. public class MainFrame {
  2. private static final int PORT=5469;
  3. public static void main(String[] args) throws Exception{
  4. IoAcceptor acceptor=new NioSocketAcceptor();
  5. IoFilter filter=new ProtocolCodecFilter(new TextLineCodecFactory());
  6. acceptor.getFilterChain().addLast("vestigge", filter);
  7. acceptor.setHandler(new ServerHandler());
  8. acceptor.bind(new InetSocketAddress(PORT));
  9. System.out.println( "服务器正在监听端口" + PORT +"...");
  10. }
  11. }

其中new ServerHandler()传入的是实现了IoHandler接口的类,代码如下:

  1. public class ServerHandler extends IoHandlerAdapter {
  2. @Override
  3. public void messageReceived(IoSession session, Object message)
  4. throws Exception {
  5. System.out.println("收到客户端消息:" + message.toString());
  6. }
  7. @Override
  8. public void exceptionCaught(IoSession session, Throwable cause)
  9. throws Exception {
  10. System.out.println("服务器出现异常:" +cause);
  11. }
  12. }

重写了父类中的messageReceived()和exceptionCaught()

一般在messageReceived()中对客户端的请求进行业务,逻辑处理

下面在命令行用telnet测试一下,

如果是win 7没有telnet,找到“打开或关闭Windows功能” ,找到telnet客户端和telnet服务端,勾选即可,

在命令行下输入telnet 127.0.0.1 5469

然后再telnet窗口中输入几个字符回车,在控制台可以看到服务器成功收到了消息:

上节中通过一个简单的例子,对Mina框架有了大体的了解,在上节的基础上,看看 怎样实现客户端与服务端的通信,

废话不多说了,直接看代码:

  1. public class Test {
  2. public static void main(String[] args) throws Exception{
  3. SocketConnector connector = new NioSocketConnector();
  4. IoFilter filter = new ProtocolCodecFilter(new TextLineCodecFactory());
  5. connector.getFilterChain().addLast("vestigge", filter);
  6. SocketAddress soketAddress = new InetSocketAddress("127.0.0.1", 5469);
  7. connector.setHandler(new ClientHandler());
  8. ConnectFuture future= connector.connect(soketAddress);
  9. future.join();
  10. if (!future.isConnected()) {
  11. System.out.println("连接服务器失败");
  12. return;
  13. }
  14. future.getSession().write("hello");
  15. }
  16. }

可以看到代码与服务器端的代码很像,也是非常的简单,这就是框架的好处,不用再重复发明轮子,省了不少事,

  1. public class ClientHandler extends IoHandlerAdapter {
  2. public void messageReceived(IoSession arg0, Object message) throws Exception {
  3. System.out.println("收到服务器消息:" + message.toString());
  4. }
  5. public void exceptionCaught(IoSession arg0, Throwable arg1)
  6. throws Exception {
  7. }
  8. }

效果演示:

登陆界面的文章 http://www.linuxidc.com/Linux/2012-11/73437.htm

就不在重复了,直接看登陆的代码,

用Mina传递字符串上节已经看过了,要实现传递对象,也非常简单,只需要修改一下过滤器:

chain.addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));

Android客户端,登陆的Activity中:

  1. public class LoginActivity extends Activity{
  2. private EditText accountEditText;
  3. private EditText passwordEditText;
  4. private CheckBox remeberCheckBox;
  5. public void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. requestWindowFeature(Window.FEATURE_NO_TITLE);
  8. setContentView(R.layout.activity_login);
  9. accountEditText=(EditText) findViewById(R.id.login_account);
  10. passwordEditText=(EditText) findViewById(R.id.login_password);
  11. remeberCheckBox=(CheckBox) findViewById(R.id.login_remember);
  12. findViewById(R.id.login_login).setOnClickListener(new OnClickListener(){
  13. public void onClick(View v) {
  14. if(accountEditText.getText().toString().equals("") ||
  15. passwordEditText.getText().toString().equals("")){
  16. Toast.makeText(LoginActivity.this, "账号或密码不能为空!", Toast.LENGTH_SHORT).show();
  17. }else{
  18. User user=new User();
  19. user.setAccount(Integer.parseInt(accountEditText.getText().toString()));
  20. user.setPassword(passwordEditText.getText().toString());
  21. user.setOperation(VQMessageType.LOGIN);
  22. boolean b=new VQClient().sendLoginInfo(user);
  23. //如果登录成功
  24. if(b){
  25. Toast.makeText(LoginActivity.this, "登陆成功!", Toast.LENGTH_SHORT).show();
  26. startActivity(new Intent(LoginActivity.this,MainActivity.class));
  27. }else{
  28. Toast.makeText(LoginActivity.this, "连接超时,登陆失败!", Toast.LENGTH_SHORT).show();
  29. }
  30. }
  31. }
  32. });
  33. }
  34. }

可以看到会调用VQClient这个类中的方法去发送登陆请求,VQClient的实现:

  1. public class VQClient {
  2. private static int PORT=5469;
  3. public boolean sendLoginInfo(User u){
  4. boolean b=false;
  5. System.setProperty("java.net.preferIPv6Addresses", "false");//2.2会有ipv6的问题,
  6. SocketConnector connector = new NioSocketConnector();
  7. connector.setConnectTimeoutMillis(300000);
  8. DefaultIoFilterChainBuilder chain=connector.getFilterChain();
  9. chain.addLast("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
  10. SocketSessionConfig cfg = connector.getSessionConfig();
  11. cfg.setUseReadOperation(true);
  12. IoSession session = connector.connect(new InetSocketAddress("10.0.2.2", PORT))
  13. .awaitUninterruptibly().getSession();
  14. //发送并等待完成
  15. session.write(u).awaitUninterruptibly();
  16. //接收
  17. ReadFuture readFuture = session.read();
  18. //接收超时
  19. if (readFuture.awaitUninterruptibly(30000,TimeUnit.SECONDS)) {
  20. VQMessage message = (VQMessage) readFuture.getMessage();
  21. //如果是登陆成功的信息
  22. if(message.getType().equals(VQMessageType.SUCCESS)){
  23. b= true;
  24. }
  25. else {
  26. b= false;
  27. }
  28. //断开连接
  29. session.close(true);
  30. session.getService().dispose();
  31. return b;
  32. }
  33. }

然后服务器端变化不大,在收到登陆请求后,会查询数据库,返回一个信息,来表明登陆成功或者失败。

  1. public void messageReceived(IoSession session, Object message)
  2. throws Exception {
  3. User user=(User) message;
  4. if(user.getOperation().equals(VQMessageType.LOGIN)){
  5. //操作数据库
  6. boolean b=new UserDao().login(user.getAccount(), user.getPassword());
  7. if(b){
  8. System.out.println(">> ["+user.getAccount()+"] 上线了");
  9. //告诉客户端登陆成功
  10. VQMessage m=new VQMessage();
  11. m.setType(VQMessageType.SUCCESS);
  12. session.write(m);
  13. }
  14. }
  15. }

最后附上测试效果:

使用Mina框架开发 QQ Android 客户端的更多相关文章

  1. GPS部标平台的架构设计(三) 基于struts+spring+hibernate+ibatis+quartz+mina框架开发GPS平台

    注意,此版本是2014年研发的基于Spring2.5和Struts2的版本,此版本的源码仍然销售,但已不再提供源码升级的服务,因为目前我们开发的主流新版本是2015-2016年近一年推出的基于spri ...

  2. SUI Mobile框架开发,android、ios表单遇到的问题

    1.页面添加区域滚动,滚动区域内元素事件无效问题 解决方法: <script type="text/javascript" charset="utf-8" ...

  3. 【FastDev4Android框架开发】RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)

    转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49992269 本文出自:[江清清的博客] (一).前言: [好消息] ...

  4. struts2中获取request、response,与android客户端进行交互(文件传递给客户端)

    用struts2作为服务器框架,与android客户端进行交互需要得到request.response对象. struts2中获取request.response有两种方法. 第一种:利用Servle ...

  5. WebService系列二:使用JDK和CXF框架开发WebService

    一.使用JDK开发WebService 服务端程序创建: 1.新建一个JDK开发webservice的服务端maven项目JDKWebServiceServer 2. 定义一个接口,使用@WebSer ...

  6. Mina框架的学习笔记——Android客户端的实现

    Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...

  7. 基于Java Mina框架的部标808服务器设计和开发

    在开发部标GPS平台中,部标808GPS服务器是系统的核心关键,决定了部标平台的稳定性和行那个.Linux服务器是首选,为了跨平台,开发语言选择Java自不待言. 我们为客户开发的部标服务器基于Min ...

  8. Android Mina框架的学习笔记

    Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络 ...

  9. 基于Java Mina框架的部标jt808服务器设计和开发

    在开发部标GPS平台中,部标jt808GPS服务器是系统的核心关键,决定了部标平台的稳定性和行那个.Linux服务器是首选,为了跨平台,开发语言选择Java自不待言.需要购买jt808GPS服务器源码 ...

随机推荐

  1. Lesson 3: The Amazing New Mobile Web

    Lesson 3: The Amazing New Mobile Web Article 1: This is Responsive by Brad Frost 各种响应式网站设计的资源. Artic ...

  2. HTML5 web开发时遇到的一个奇葩问题。

    昨天做了一个手机端的H5 页面. 首先就是各种兼容测试,调整修复..一系列操作之后,拿过来N多手机神马华为.小米.三星.水果5.6.plus,一番测试之后.嗯,还不错,稍作等待之后就上线了. 这是分割 ...

  3. python_基本语法_01

    离毕业工作还有几个月,本来想早点去公司实习,无奈gb学校不给放.好吧,既然这样,就学门语言. 参考与 http://www.cnblogs.com/vamei ,我是跟着这位博客牛人的博客教程学的,具 ...

  4. csv内存流文件流

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...

  5. 解决jsp页面乱码问题

    页面也需要设置转码的:页面:(.jsp) <%@ page language="java" import="java.util.*" pageEncodi ...

  6. MarkdownPad 使用 MathJax

    一直想要在MarkdownPad中支持数学公式,终于找到了一个方法: 在MarkdownPad中,点击"Tools > Options > Advanced > HTML ...

  7. Android Recovery的汉化 显示中文

    Android Recovery的汉化 显示中文,有需要的朋友可以参考下. 首先下载开源的recovery源码,地址为https://github.com/xiaolu/android_bootabl ...

  8. 剑指offer之O(1)算法删除指针所指向的节点

    题目如图: 1.把要删除pToBeDeleted的节点的后面节点覆盖点要删除的节点pToBeDeleted 2.要考虑如果删除的节点是最后一个节点怎么办 3.要考虑如果总共只有一个节点,删除的是头结点 ...

  9. android Uri获取真实路径转换成File的方法

    Uri uri = data.getData(); String[] proj = { MediaStore.Images.Media.DATA }; Cursor actualimagecursor ...

  10. 8.2.1.15 ORDER BY Optimization ORDER BY 优化

    8.2.1.15 ORDER BY Optimization ORDER BY 优化 在一些情况下, MySQL 可以使用一个索引来满足一个ORDER BY 子句不需要做额外的排序 index 可以用 ...