服务端代码:
- package com.xd.nms.example;
- import java.io.IOException;
- import java.net.InetSocketAddress;
- 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.nio.NioSocketAcceptor;
- import com.xd.nms.util.ByteAndStr16;
- /**
- * @说明 Mina TCP 服务端
- * @author 崔素强
- * @version 1.0
- * @since
- */
- public class MinaTcpServer extends IoHandlerAdapter {
- public static final int PORT = 18567;
- public MinaTcpServer() throws IOException {
- NioSocketAcceptor acceptor = new NioSocketAcceptor();
- acceptor.setHandler(this);
- acceptor.bind(new InetSocketAddress(PORT));
- System.out.println("TCP服务启动,端口:" + PORT);
- }
- public static void main(String[] args) throws IOException {
- new MinaTcpServer();
- }
- @Override
- public void messageReceived(IoSession session, Object message)
- throws Exception {
- IoBuffer bbuf = (IoBuffer) message;
- byte[] byten = new byte[bbuf.limit()];
- bbuf.get(byten, bbuf.position(), bbuf.limit());
- System.out.println("收到消息:" + ByteAndStr16.Bytes2HexString(byten));
- byte[] bts = new byte[10];
- for(int i=0;i<10;i++){
- bts[i] = (byte)i;
- }
- IoBuffer buffer = IoBuffer.allocate(10);
- buffer.put(bts);
- buffer.flip();
- session.write(buffer);
- // // 拿到所有的客户端Session
- // Collection<IoSession> sessions = session.getService().getManagedSessions().values();
- // // 向所有客户端发送数据
- // for (IoSession sess : sessions) {
- // sess.write(buffer);
- // }
- }
- @Override
- public void sessionClosed(IoSession session) throws Exception {
- System.out.println("会话关闭");
- }
- @Override
- public void exceptionCaught(IoSession session, Throwable cause)
- throws Exception {
- System.out.println("会话异常");
- super.exceptionCaught(session, cause);
- }
- @Override
- public void messageSent(IoSession iosession, Object obj) throws Exception {
- System.out.println("服务端消息发送");
- super.messageSent(iosession, obj);
- }
- @Override
- public void sessionCreated(IoSession iosession) throws Exception {
- System.out.println("会话创建");
- super.sessionCreated(iosession);
- }
- @Override
- public void sessionIdle(IoSession iosession, IdleStatus idlestatus)
- throws Exception {
- System.out.println("会话休眠");
- super.sessionIdle(iosession, idlestatus);
- }
- @Override
- public void sessionOpened(IoSession iosession) throws Exception {
- System.out.println("会话打开");
- super.sessionOpened(iosession);
- }
- }
服务端建立端口监听后,收到消息后进入messageReceived()方法,示例处理是打印该消息,然后组装了一个0-9的数据返回回去
注意,即使使用的是Mina,仍需做分包、粘包,等处理,例如有时一条数据不是一次发过来的
客户端程序:
- package com.xd.nms.example;
- import java.net.InetSocketAddress;
- import org.apache.mina.core.buffer.IoBuffer;
- import org.apache.mina.core.future.ConnectFuture;
- import org.apache.mina.core.service.IoConnector;
- 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.nio.NioSocketConnector;
- import com.xd.nms.util.ByteAndStr16;
- /**
- * @说明 Mina TCP客户端
- * @author 崔素强
- * @version 1.0
- * @since
- */
- public class MinaTcpClient extends IoHandlerAdapter {
- private IoConnector connector;
- private static IoSession session;
- public MinaTcpClient() {
- connector = new NioSocketConnector();
- connector.setHandler(this);
- ConnectFuture connFuture = connector.connect(new InetSocketAddress("localhost", MinaTcpServer.PORT));
- connFuture.awaitUninterruptibly();
- session = connFuture.getSession();
- System.out.println("TCP 客户端启动");
- }
- public static void main(String[] args) throws Exception {
- MinaTcpClient client = new MinaTcpClient();
- for(int j=0;j<2;j++){ // 发送两遍
- byte[] bts = new byte[20];
- for (int i = 0; i < 20; i++) {
- bts[i] = (byte) i;
- }
- IoBuffer buffer = IoBuffer.allocate(20);
- // 自动扩容
- buffer.setAutoExpand(true);
- // 自动收缩
- buffer.setAutoShrink(true);
- buffer.put(bts);
- buffer.flip();
- session.write(buffer);
- Thread.sleep(2000);
- }
- // 关闭会话,待所有线程处理结束后
- client.connector.dispose(true);
- }
- @Override
- public void messageReceived(IoSession iosession, Object message)
- throws Exception {
- IoBuffer bbuf = (IoBuffer) message;
- byte[] byten = new byte[bbuf.limit()];
- bbuf.get(byten, bbuf.position(), bbuf.limit());
- System.out.println("客户端收到消息" + ByteAndStr16.Bytes2HexString(byten));
- }
- @Override
- public void exceptionCaught(IoSession session, Throwable cause)
- throws Exception {
- System.out.println("客户端异常");
- super.exceptionCaught(session, cause);
- }
- @Override
- public void messageSent(IoSession iosession, Object obj) throws Exception {
- System.out.println("客户端消息发送");
- super.messageSent(iosession, obj);
- }
- @Override
- public void sessionClosed(IoSession iosession) throws Exception {
- System.out.println("客户端会话关闭");
- super.sessionClosed(iosession);
- }
- @Override
- public void sessionCreated(IoSession iosession) throws Exception {
- System.out.println("客户端会话创建");
- super.sessionCreated(iosession);
- }
- @Override
- public void sessionIdle(IoSession iosession, IdleStatus idlestatus)
- throws Exception {
- System.out.println("客户端会话休眠");
- super.sessionIdle(iosession, idlestatus);
- }
- @Override
- public void sessionOpened(IoSession iosession) throws Exception {
- System.out.println("客户端会话打开");
- super.sessionOpened(iosession);
- }
- }
向服务端发送两次0-19的数据,收到消息后同样进入messageReceived()方法,处理同样是打印显示!
打印结果:
- TCP服务启动,端口:18567
- 会话创建
- 会话打开
- 收到消息:00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13
- 服务端消息发送
- 收到消息:00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13
- 服务端消息发送
- 会话关闭
- 客户端会话创建
- 客户端会话打开
- TCP 客户端启动
- 客户端消息发送
- 客户端收到消息00 01 02 03 04 05 06 07 08 09
- 客户端消息发送
- 客户端收到消息00 01 02 03 04 05 06 07 08 09
- 客户端会话关闭