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客户端勾选 确定)
Java基础06 MINA框架介绍与服务器端程序 167 168_第1张图片
然后使用telnet连接此服务器
Java基础06 MINA框架介绍与服务器端程序 167 168_第2张图片
连接成功
Java基础06 MINA框架介绍与服务器端程序 167 168_第3张图片
从命令行输入消息 服务器会收到 并且返回 echo+消息
Java基础06 MINA框架介绍与服务器端程序 167 168_第4张图片


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);
    }
}

先启动服务器
Java基础06 MINA框架介绍与服务器端程序 167 168_第5张图片
再启动客户端
Java基础06 MINA框架介绍与服务器端程序 167 168_第6张图片
连接到了服务器
Java基础06 MINA框架介绍与服务器端程序 167 168_第7张图片
输入hello 服务器返回echo hello
Java基础06 MINA框架介绍与服务器端程序 167 168_第8张图片
因为写的死循环 所以就可以一直输入
Java基础06 MINA框架介绍与服务器端程序 167 168_第9张图片
服务器也会收到消息
Java基础06 MINA框架介绍与服务器端程序 167 168_第10张图片
Java基础06 MINA框架介绍与服务器端程序 167 168_第11张图片
客户端停止的话 那个左边的红色按钮
服务器就会收到消息
Java基础06 MINA框架介绍与服务器端程序 167 168_第12张图片

第三种 可以使用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 + '\'' +
                '}';
    }
}

其他的看上面的代码
结果 先期启动服务器
Java基础06 MINA框架介绍与服务器端程序 167 168_第13张图片
再启动客户端
Java基础06 MINA框架介绍与服务器端程序 167 168_第14张图片
输入
Java基础06 MINA框架介绍与服务器端程序 167 168_第15张图片
服务器收到
Java基础06 MINA框架介绍与服务器端程序 167 168_第16张图片

你可能感兴趣的:(Java)