mina 用于接收byte数组消息处理的服务端

mina 用于接收bytes消息处理的服务端

做过简单测试,其他 blog 说的串包,丢包,跳包什么的还没测过。 因为只是心血来潮用来做模拟第三方测试桩用的,有兴趣的可以测一下跳包什么的问题。
maven 引入

    <dependency>
        <groupId>org.apache.mina</groupId>
        <artifactId>mina-core</artifactId>
        <version>2.1.3</version>
    </dependency>

如果是 springboot 的容器,丢工程的启动类里面就可以随工程启动服务了。

自定义业务处理的handler

package com.primeton.etc.tools;

import org.apache.mina.core.buffer.IoBuffer;
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.transport.socket.SocketSessionConfig;

import java.io.IOException;

public class MinaMyIoHandlerAdapter extends IoHandlerAdapter {

    public MinaMyIoHandlerAdapter()  {

    }

    @Override
    public void messageReceived(IoSession session, Object message)
            throws Exception {

        // 用 IoBuffer 取, 就不用 decoder 了。
        IoBuffer bbuf = (IoBuffer) message;
        byte[] bytes = new byte[bbuf.limit()];
        bbuf.get(bytes, bbuf.position(), bbuf.limit());

        byte[] responseMsgBytes = null;
        
        //TODO 业务处理
        
        responseMsgBytes = bytes;
        //返回数据 , 将返回报文返回给客户端  当封装成 IoBuffer 时, 不需要自定义的 encoder
        IoBuffer buffer = IoBuffer.allocate(responseMsg.length);
        buffer.put(responseMsg);
        buffer.flip();
        session.write(buffer);
        //这里千万不能加 session.closeNow()
    }
    @Override
    public void sessionClosed(IoSession session) throws Exception {
    	super.sessionClosed(session);
    }
    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
            throws Exception {
        cause.printStackTrace();
        session.closeNow();
    }
    @Override
    public void messageSent(IoSession iosession, Object obj) throws Exception {
        super.messageSent(iosession, obj);
    }
    @Override
    public void sessionCreated(IoSession iosession) throws Exception {
        super.sessionCreated(iosession);
        SocketSessionConfig cfg = (SocketSessionConfig) iosession.getConfig();
        cfg.setReceiveBufferSize(2 * 1024 * 1024);
        cfg.setReadBufferSize(2 * 1024 * 1024);
        cfg.setKeepAlive(true);
        cfg.setSoLinger(0); //解决可能会很多 time_wait

    }
    @Override
    public void sessionIdle(IoSession iosession, IdleStatus idlestatus)
            throws Exception {
        super.sessionIdle(iosession, idlestatus);
        //超时处理吧, 当session 有 5*idletime 的实际时, 服务端主动关闭
        if (iosession.getIdleCount(idlestatus) == 5){
            iosession.closeNow();
        }
    }
    @Override
    public void sessionOpened(IoSession iosession) throws Exception {
        super.sessionOpened(iosession);
    }

}

服务类

package com.primeton.etc.tools;

import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

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

public class MinaServer  {
    private NioSocketAcceptor acceptor = null;

    public MinaServer(int port) throws IOException {
        acceptor = new NioSocketAcceptor();
        // 设置读取数据的缓冲区大小
        acceptor.getSessionConfig().setReadBufferSize(1024*102400);
        // 读写通道10秒内无操作进入空暇状态
        acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
        //绑定一个日志处理器
        acceptor.getFilterChain().addLast("logger",new LoggingFilter());

		//绑定业务处理 handler
        acceptor.setHandler(new MinaMyIoHandlerAdapter());
		//绑定端口
        acceptor.bind(new InetSocketAddress(port));

        System.out.println("TCP服务启动,端口:" + port);
    }
	
	//测试启动
    public static void main(String[] args) throws IOException {
        new MinaServer(10000);
    }
}


测试类 java socket

public static Serializable sendMessage(String ip,int port,int timeout,Serializable msg){
        Socket socket = null;
        InputStream is = null;
        OutputStream os = null;

        try {
            InetAddress addr = InetAddress.getByName(ip);
            socket = new Socket();
            socket.connect(new InetSocketAddress(addr,port),timeout);

            System.out.println("socket 连接成功 ");

            socket.setSendBufferSize(102400);

            is = socket.getInputStream();
            os = socket.getOutputStream();
            os.write(String.format("%04d",((byte[])msg).length).getBytes());
            os.write((byte[])msg);
            System.out.println("写收据到etc成功 ");
            os.flush();

            byte[] head = new byte[4];
            System.out.println(is.available());
            is.read(head,0,4);
            int nlen = Integer.parseInt(new String(head));

            System.out.println("nlen = "+nlen);

            byte[] bytes = new byte[nlen];
            is.read(bytes,0,nlen);

            System.out.println("接收返回收据成功:" + new String(bytes));
            os.close();
            is.close();
            socket.close();

            return conect(head,bytes);

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (os != null){
                    os.close();
                }
                if (is != null){
                    is.close();
                }
                if (socket != null){
                    socket.close();
                }

            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return null;
    }


    public static void main(String[] args) {

        byte[] msg = "asdag".getBytes();

        SocketUtil.sendMessage("127.0.0.1",10000,60000,msg);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值