Java使用mina开发TCP服务

1.导入依赖

        <!-- https://mvnrepository.com/artifact/org.apache.mina/mina-core -->
        <dependency>
            <groupId>org.apache.mina</groupId>
            <artifactId>mina-core</artifactId>
            <version>2.2.1</version>
        </dependency>

2.编写TCP服务端

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.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

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

public class TCPServer implements Runnable {

    private static final Logger logger = Logger.getLogger(TCPServer.class);

    private final int port = 55555;

    @Override
    public void run() {

        IoAcceptor acceptor = new NioSocketAcceptor();
        acceptor.getSessionConfig().setReadBufferSize(2048);
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);

        // 编写过滤器
//        acceptor.getFilterChain().addLast("codec",
//                new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"),
//                        LineDelimiter.WINDOWS.getValue(),
//                        LineDelimiter.WINDOWS.getValue()))
//        );
        //加入解码器
        acceptor.getFilterChain().addLast("objectFilter",new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));

        // 注册IoHandler
        acceptor.setHandler(new TCPServerHandler());

        // 绑定端口
        try {
            acceptor.bind(new InetSocketAddress(port));
        } catch (IOException e) {
            logger.error("服务端口被占用:" + port);
        }


        logger.info("TCPServer启动成功 port:" + port);
    }
}

2.注册服务端IoHandler,继承 IoHandlerAdapter 重写父类方法

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 org.apache.mina.filter.FilterEvent;

import java.net.InetSocketAddress;
import java.util.HashMap;

public class TCPServerHandler extends IoHandlerAdapter {

    private static final Logger logger = Logger.getLogger(TCPServerHandler.class);

    @Override
    public void sessionCreated(IoSession session) throws Exception {
        super.sessionCreated(session);
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        logger.info(session.getRemoteAddress() + "已连接...");
    }

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

    @Override
    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
        super.sessionIdle(session, status);
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        // 连接异常处理
        logger.error(session.getRemoteAddress() + cause.getMessage());
    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        if (message instanceof User) {
            User request = (User) message;
        }
    }

    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        super.messageSent(session, message);
    }

    @Override
    public void inputClosed(IoSession session) throws Exception {
        super.inputClosed(session);
    }

    @Override
    public void event(IoSession session, FilterEvent event) throws Exception {
        super.event(session, event);
    }
}

3.编写TCP客户端

import org.apache.log4j.Logger;
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.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;

import java.net.InetSocketAddress;

public class TCPClient implements Runnable {

    private static final Logger logger = Logger.getLogger(TCPClient.class);

    private final String ip = "127.0.0.1";

    private final int port = 55555;

    //创建连接客户端
    private static final IoConnector connector = new NioSocketConnector();

    private static ConnectFuture connect = null;

    @Override
    public void run() {
        logger.info("连接服务:" + ip);

        //设置连接超时
        connector.setConnectTimeoutMillis(30000);

//        connector.getFilterChain().addLast("codec",
//                new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"),
//                        LineDelimiter.WINDOWS.getValue(),
//                        LineDelimiter.WINDOWS.getValue())));
        connector.getFilterChain().addLast("objectFilter", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));

        connector.setHandler(new TCPClientHandler());

        // 设置默认访问地址
        connector.setDefaultRemoteAddress(new InetSocketAddress(ip, port));
        // 添加重连监听
        connector.addListener(new TCPClientIoServiceListener());

        connect = connector.connect(new InetSocketAddress(ip, port));

        // 阻塞检测是否连接成功
        if (!status()) {
            reconnection();
        }
        logger.info("connected...");

    }

    /**
     * 服务连接状态
     * @return
     */
    public static boolean status() {
        try {
            connect.awaitUninterruptibly();// 等待连接创建成功
            IoSession session = connect.getSession();// 获取会话
            return session.isConnected();
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 尝试重连
     */
    public static void reconnection() {
        while (true) {
            try {
                ThreadUtil.sleep(1000 * 3);
                ConnectFuture future = connector.connect();
                future.awaitUninterruptibly();// 等待连接创建成功
                IoSession session = future.getSession();// 获取会话
                if (session.isConnected()) {
                    logger.info("断线重连[" + connector.getDefaultRemoteAddress() + "]成功...");
                    break;
                }
            } catch (Exception ex) {
                logger.info("重连服务器登录失败,3秒后重试:" + ex.getMessage());
            }
        }
    }

}

4.同样需要注册客户端IoHandler

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 org.apache.mina.filter.FilterEvent;

public class TCPClientHandler extends IoHandlerAdapter {

    private static final Logger logger = Logger.getLogger(TCPClientHandler.class);

    @Override
    public void sessionCreated(IoSession session) throws Exception {
        super.sessionCreated(session);
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        // 向TCP服务发送消息
        session.write(new User());
    }

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

    @Override
    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
        super.sessionIdle(session, status);
    }

    @Override
    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
        // 断开连接异常处理
        logger.error(session.getRemoteAddress() + cause.getMessage());
    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        super.messageReceived(session, message);
    }

    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        super.messageSent(session, message);
    }

    @Override
    public void inputClosed(IoSession session) throws Exception {
        super.inputClosed(session);
    }

    @Override
    public void event(IoSession session, FilterEvent event) throws Exception {
        super.event(session, event);
    }
}

5.监听服务(用于掉线自动尝试重连)

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

import java.net.InetSocketAddress;

public class TCPClientIoServiceListener implements IoServiceListener {

    private static final Logger logger = Logger.getLogger(TCPClientIoServiceListener.class);

    @Override
    public void serviceActivated(IoService ioService) throws Exception {

    }

    @Override
    public void serviceIdle(IoService ioService, IdleStatus idleStatus) throws Exception {

    }

    @Override
    public void serviceDeactivated(IoService ioService) throws Exception {

    }

    @Override
    public void sessionCreated(IoSession ioSession) throws Exception {

    }

    @Override
    public void sessionClosed(IoSession ioSession) throws Exception {

    }

    @Override
    public void sessionDestroyed(IoSession ioSession) throws Exception {
        logger.info(((InetSocketAddress) ioSession.getRemoteAddress()).getHostString() + "会话已销毁...");
        TCPClient.reconnection();
    }

}

 完事了...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今晚哒老虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值