Java基础06 MINA框架介绍与服务器端程序 167 168

MINA框架
1、什么是MINA? 一句话就是:一个简洁易用的基于 TCP/IP 通信的 JAVA框架。
2、下载地址:http://mina.apache.org
3、一个简单的网络程序需要的最少jar包:mina-core-2.0.16.jar、slf4j-api-1.7.21.jar
4、开发一个 Mina 应用,简单的说,就是创建连接,设定过滤规则,编写自己的消息处理器
5、示例:
//创建一个非阻塞的Server端Socket,用NIO
SocketAcceptor acceptor = new NioSocketAcceptor(); //创建接收数据的过滤器
DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
//设定这个过滤器将一行一行(/r/n)的读取数据
chain.addLast(“myChin”, new ProtocolCodecFilter(new TextLineCodecFactory()));
//设定服务器端的消息处理器:一个SampleMinaServerHandler对象
acceptor.setHandler(new SampleMinaServerHandler());
int bindPort = 9999;
//绑定端口,启动服务器
try {acceptor.bind(new InetSocketAddress(bindPort)); } catch (IOException e) {e.printStackTrace();}
System.out.println("Mina Server is Listing on:= " + bindPort);


   public class SampleMinaServerHandler extends IoHandlerAdapter{
        public void sessionOpened(IoSession session) throws Exception {
            super.sessionOpened(session);
            System.out.println("incomming client : "+session.getRemoteAddress());
        }
        public void sessionClosed(IoSession session) throws Exception {
            super.sessionClosed(session);
            System.out.println("one Clinet Disconnect !");
        }
        public void messageReceived(IoSession session, Object message) throws Exception {
            //我们己设定了服务器解析消息的规则是一行一行读取,这里就可转为String:
            String s=(String)message;
            System.out.println("收到客户机发来的消息: "+s);
            session.write("echo:"+s);
        }
    }

1、使用telnet测试:telnet localhost 9999
2、编写客户端:
NioSocketConnector connector = new NioSocketConnector(); 创建接收数据的过滤器
DefaultIoFilterChainBuilder chain = connector.getFilterChain();
设定这个过滤器将一行一行(/r/n)的读取数据
chain.addLast("myChin", new ProtocolCodecFilter(new  TextLineCodecFactory()));
设定服务器端的消息处理器:一个 SamplMinaServerHandler 对象
connector.setHandler(new SampleMinaClientHandler()); 
connector.setConnectTimeout(30);// Set connect timeout. 
连接到服务器:
ConnectFuture cf = connector.connect(new InetSocketAddress("localhost", 9999));
Wait for the connection attempt to be finished.
cf.awaitUninterruptibly(); 
发送消息
//cf.getSession().getCloseFuture().awaitUninterruptibly();
//connector.dispose();

使用telnet测试
先启动服务器 有些包的依赖错误 先不管
最后一句话输出了
代表服务器启动了
这里注意 这个是Socket NIO 非阻塞的服务器端 即立即返回
所以一启动就会输出这句话 但是并没有结束 里面即服务器线程依然运行
(telnet客户端如果未开启服务 win10 双击桌面的控制面板 打开大图标查看模式 找到程序和功能 左边启用和关闭Windows功能 找到telnet客户端勾选 确定)
在这里插入图片描述
然后使用telnet连接此服务器
在这里插入图片描述
连接成功
在这里插入图片描述
从命令行输入消息 服务器会收到 并且返回 echo+消息
在这里插入图片描述


public class SampleMinaClientHandler extends IoHandlerAdapter {
当一个客端端连结进入时
public void sessionOpened(IoSession session) throws Exception { 
	System.out.println("incomming client :"+session.getRemoteAddress()); session.write("我来啦........");
}
当一个客户端关闭时
public void sessionClosed(IoSession session) {
	System.out.println("one Clinet Disconnect !"); }
当客户端发送的消息到达时:
public void messageReceived(IoSession session, Object message)throws Exception {
我们己设定了服务器解析消息的规则是一行一行读取,这里就可转为 String: 
	String s=(String)message;
	System.out.println("服务器发来的收到消息: "+s);
	测试将消息回送给客户端 
	session.write(s);
} }


第二种就是使用客户端代码 测试与服务器的连接 这样可以传送简单的字符串
下面注释的部分是传送的简单字符串
没注释的是传送的对象
正式代码
服务器代码

package com.vince.mina;

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;

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

/**
 * Created by vince on 2017/6/8.
 */
public class Server {

    public static void main(String[] args) {

        //创建一个非阻塞的Server端Socket NIO
        SocketAcceptor acceptor = new NioSocketAcceptor();
        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
        //设定一个过滤器,一行一行的读取数据(/r/n)
        //chain.addLast("myChin",new ProtocolCodecFilter(new TextLineCodecFactory()));
        //设定过滤器以对象为单位读取数据
        chain.addLast("objectFilter",new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
        //设置服务器端的消息处理器
        acceptor.setHandler(new MinaServerHandler());
        int port = 9999; //服务器的端口号
        try {
            //绑定端口,启动服务器(不会阻塞,立即返回)
            acceptor.bind(new InetSocketAddress(port));
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Mina Server running, listener on : "+ port);
    }
}

客户端代码

package com.vince.mina;

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;

import java.net.InetSocketAddress;
import java.util.Scanner;

/**
 * Created by vince on 2017/6/8.
 */
public class Client {
    public static void main(String[] args) {

        //创建连接
        NioSocketConnector connector = new NioSocketConnector();
        DefaultIoFilterChainBuilder chain = connector.getFilterChain();
//        chain.addLast("myChin",new ProtocolCodecFilter(new TextLineCodecFactory()));
        //设定过滤器以对象为单位读取数据
        chain.addLast("objectFilter",new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));

        connector.setHandler(new MinaClientHandler());
        connector.setConnectTimeoutMillis(10000);
        //连接服务器
        ConnectFuture cf = connector.connect(new InetSocketAddress("localhost",9999));
        cf.awaitUninterruptibly();//等待连接成功
        Scanner input = new Scanner(System.in);

        while(true) {
//            System.out.println("请输入:");
//            String info = input.nextLine();
//            //发送消息
//            cf.getSession().write(info);

            //以对象的方式传输数据
            Message msg = new Message();
            System.out.println("form:");
            msg.setFrom(input.nextLine());
            System.out.println("to:");
            msg.setTo(input.nextLine());
            System.out.println("info:");
            msg.setInfo(input.nextLine());
            msg.setType("send");

            cf.getSession().write(msg);
        }
        //这两句用不上 因为上面写的是死循环
        //等待服务器连接关闭,结束长连接
       // cf.getSession().getCloseFuture().awaitUninterruptibly();
       // connector.dispose();//关闭连接
    }
}

服务器的处理器

package com.vince.mina;

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

/**
 * Created by vince on 2017/6/8.
 * 服务器端的消息处理器
 */
public class MinaServerHandler extends IoHandlerAdapter {
    //一次会话被打开
    @Override
    public void sessionOpened(IoSession session) throws Exception {
        super.sessionOpened(session);
        System.out.println("welcome client "+session.getRemoteAddress());
    }
    //会话关闭
    @Override
    public void sessionClosed(IoSession session) throws Exception {
        super.sessionClosed(session);
        System.out.println("client closed");
    }

    //接收消息
    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        super.messageReceived(session, message);
        //String msg = (String) message;//接收到的消息对象
        Message msg = (Message) message;

        System.out.println("收到客户端发来的消息:"+msg);
        msg.setInfo("吃好吃的");
        //向客户端发送消息对象
        session.write(msg);
    }
}

客户端的处理器

package com.vince.mina;

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

import javax.sound.midi.Soundbank;

/**
 * Created by vince on 2017/6/8.
 */
public class MinaClientHandler extends IoHandlerAdapter {

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        super.sessionOpened(session);
        System.out.println("sessionOpened");
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        super.sessionClosed(session);
        System.out.println("sessionClosed");
    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        super.messageReceived(session, message);
        //String msg = (String) message;
        Message msg = (Message)message;
        System.out.println(msg);
    }
}

先启动服务器
在这里插入图片描述
再启动客户端
在这里插入图片描述
连接到了服务器
在这里插入图片描述
输入hello 服务器返回echo hello
在这里插入图片描述
因为写的死循环 所以就可以一直输入
在这里插入图片描述
服务器也会收到消息
在这里插入图片描述
在这里插入图片描述
客户端停止的话 那个左边的红色按钮
服务器就会收到消息
在这里插入图片描述

第三种 可以使用Mina穿送对象
记得要序列化对象
注意服务器和客户端两端在设置过滤器时不再是IO的输入异常了
而是 对象序列化的Factory

接受的时候就可以使用我们自己定义的实体类对象接收Object对象了

使用 Mina 直接传送对象
1public class Userinfo implements java.io.Serializable
2、	服务器,客户端都设定以对象为单位
	设定这个过滤器将以对象为单位读取数据
	ProtocolCodecFilter filter= new ProtocolCodecFilter(new ObjectSerializationCodecFactory());
	chain.addLast("objectFilter",filter);
3、接收对象
	public void messageReceived(IoSession session, Object message) throws Exception {
		我们己设定了服务器解析消息的规则一个Userinfo对象为单位传输: 
		Userinfo us=(Userinfo)message;
	}

正式代码
Message

package com.vince.mina;

import java.io.Serializable;

/**
 * Created by vince on 2017/6/8.
 */
public class Message implements Serializable {

    private String from;
    private String to;
    private String type;
    private String info;

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }

    @Override
    public String toString() {
        return "Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", type='" + type + '\'' +
                ", info='" + info + '\'' +
                '}';
    }
}

其他的看上面的代码
结果 先期启动服务器
在这里插入图片描述
再启动客户端
在这里插入图片描述
输入
在这里插入图片描述
服务器收到
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值