使用mina 基于tcp协议实现客户端和服务端进行通信

Posted 健康平安的活着

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用mina 基于tcp协议实现客户端和服务端进行通信相关的知识,希望对你有一定的参考价值。

一 基于tcp协议实现客户端和服务端进行通信

1.1  说明

话不多说,上代码,

注意:使用udp不能使用telnet进行向服务端发送信息

1.2 服务端

1.2.1 服务端

package com.ljf.mina.demo.socket;

import com.ljf.mina.demo.handler.MyHandler;
import org.apache.log4j.Logger;
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.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
import org.apache.mina.transport.socket.nio.NiosocketAcceptor;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.concurrent.Executors;

/**
 * @ClassName: MinaServer
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/08/02 09:06:24 
 * @Version: V1.0
 **/
public class MinaServer {
    //private final static Logger logger = LogManager.getLogger(MinaServer.class);
    private static Logger logger = Logger.getLogger(MinaServer.class);
    // 绑定的端口
    private static final int MINA_PORT = 7080;
    public static void main(String[] args) {
        dealData();
     System.out.println("mina 服务启动成功!!!");
    }

    public static void  dealData(){
        IoAcceptor acceptor;
        try {
            // 创建一个非阻塞的server端的Socket
            acceptor = new NioSocketAcceptor();
           // acceptor=new NioDatagramAcceptor();
            // 设置编码过滤器(使用Mina提供的文本换行符编解码器)
            acceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                    new TextLineCodecFactory(
                            Charset.forName("UTF-8") ,
                            LineDelimiter.WINDOWS.getValue(),
                            LineDelimiter.WINDOWS.getValue()
                    )
            ));
            // 添加自定义的过滤器
           // acceptor.getFilterChain().addFirst("filter", new MyServerFilter());
            // 设置读取数据的缓冲区大小
            acceptor.getSessionConfig().setReadBufferSize(1024);
            // 设置读写通道无操作进入空闲状态的时间 10ms
            acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
            // 绑定真正的逻辑处理
            acceptor.setHandler(new MyHandler());
            // 绑定端口
            acceptor.bind(new InetSocketAddress(MINA_PORT));
           // acceptor.getFilterChain().addLast("threadPool", new ExecutorFilter(Executors.newCachedThreadPool()));
            logger.info("Mina服务端启动成功,监听:" + MINA_PORT);
        } catch (IOException e) {
            e.printStackTrace();
            logger.error("服务端启动出错-----" + e);
        }
    }
}

1.2.2 handler

package com.ljf.mina.demo.handler;


import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

import java.util.Date;

/**
 * @ClassName: MyHandler
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/08/02 09:38:41 
 * @Version: V1.0
 **/
public class MyHandler extends IoHandlerAdapter {
   // private static final Logger logger = LogManager.getLogger(MyHandler.class);
    private static Logger logger = Logger.getLogger(MyHandler.class);
    public MyHandler() {
        super();
    }

    @Override
    public void sessionCreated(IoSession session) throws Exception {
        logger.info("服务端与客户端连接成功.....");
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        logger.info("服务端与客户端连接打开....");
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        logger.info("服务端与客户端连接关闭.....");
    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
        logger.info("服务端进入空闲状态......");
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        logger.error("服务端发生异常", cause);
    }
    /**
    * @author liujianfu
    * @description       服务端接收到的信息
    * @date 2021/8/2 9:41
    * @param [session, message]
    * @return void
    */
    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        System.out.println("服务端接受到消息:" + message);
        logger.info("服务端接受到消息为:【:" + message+"】");
        // 如果接受到exit,则退出程序
        if (message.equals("exit")) {
            session.closeNow();
        }
        Date date = new Date();
        session.write("hello,我是服务端,当前时间为:"+date);
    }

    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        logger.info("服务端发送消息成功");
    }

    @Override
    public void inputClosed(IoSession session) throws Exception {
        logger.info("输入关闭");
    }
}

1.3 客户端

1.3.1 客户端

package com.ljf.mina.demo.socket;

import com.ljf.mina.demo.handler.MyClientHandler;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

/**
 * @ClassName: MinaClient
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/08/02 13:51:18 
 * @Version: V1.0
 **/
public class MinaClient {


    // 定义IP地址
    private static final String MINA_HOST = "127.0.0.1";
    // 定义端口
    private static final int MINA_PORT = 7080;

    public static void main(String[] args) throws InterruptedException {
            dealClientData();
    }
    public static void  dealClientData(){
        IoSession ioSession;
        // 创建一个非阻塞的客户端
        IoConnector ioConnector = new NioSocketConnector();
        // 设置超时时间
        ioConnector.setConnectTimeoutMillis(30000);
        // 设置编码解码器
        ioConnector.getFilterChain().addLast("codec", new ProtocolCodecFilter(
                new TextLineCodecFactory(
                        Charset.forName("UTF-8"),
                        LineDelimiter.WINDOWS.getValue(),
                        LineDelimiter.WINDOWS.getValue()
                )
        ));
        // 添加自定义过滤器
       // ioConnector.getFilterChain().addFirst("filter", new MyClientFilter());
        // 绑定逻辑处理类
        ioConnector.setHandler(new MyClientHandler());
        // 创建连接
        ConnectFuture future = ioConnector.connect(new InetSocketAddress(MINA_HOST, MINA_PORT));
        // 等待连接创建完成
        future.awaitUninterruptibly();
        // 获取连接session
        ioSession = future.getSession();
        // 发送数据
        ioSession.write("Mina是一个基于NIO的网络框架,使用它编写程序时,可以专注于业务处理,而不用过于关心IO操作,Mina");
        // 等待关闭连接
        ioSession.getCloseFuture().awaitUninterruptibly();
        ioConnector.dispose();
    }
}


1.3.2 client的handler

package com.ljf.mina.demo.handler;

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

/**
 * @ClassName: MyClientHandler
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/08/02 13:52:24 
 * @Version: V1.0
 **/
public class MyClientHandler extends IoHandlerAdapter {
    //private static final Logger logger = LogManager.getLogger(com.ljf.mina.demo.socket.MyClientHandler.class);
    private static Logger logger = Logger.getLogger(MyClientHandler.class);
    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        logger.error("客户端发生异常",cause);
    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        logger.info("客户端接收到数据:" + message);
    }
}

1.3 调试

服务端 

客户端:

 代码地址:https://gitee.com/jurf-liu/mina-demo.git

以上是关于使用mina 基于tcp协议实现客户端和服务端进行通信的主要内容,如果未能解决你的问题,请参考以下文章

轻松上手NIO的框架技术Netty,Mina,不看你肯定后悔!!!

mina中的Tcp粘包,半包的问题

Mina TCP服务端客户端 示例

Mina文档 02-基础

浅析WebSocket协议及其实现

基于TCP的客户端服务器端socket编程