netty4.x初试,简单的通讯

一个简单的聊天部分,网络上的一堆东东,有完整的不完整的,留一手的太多,还是自己写一个完整的,留自己用就好了

设计目的:
时间基本的消息为
|消息长度(4个字节)|cmd(short)|消息体|
的消息通讯方式

package com.codec;

public class NetMsg {

    private short cmd;
    private byte[] data;

    public NetMsg(){

    }

    public NetMsg(short cmd, byte[] data){
        this.cmd = cmd;
        this.data = data;
    }

    public short getCmd() {
        return cmd;
    }
    public void setCmd(short cmd) {
        this.cmd = cmd;
    }
    public byte[] getData() {
        return data;
    }
    public void setData(byte[] data) {
        this.data = data;
    }


}
package com.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

public class MsgEncode extends MessageToByteEncoder<NetMsg> {

    @Override
    protected void encode(ChannelHandlerContext ctx, NetMsg m, ByteBuf out) throws Exception {
        int body = 0;
        if (m.getData() != null){
            body = m.getData().length;
        }

        int total = 2 + body;
        out.writeInt(total);
        out.writeShort(m.getCmd());
        if (m.getData() != null){
            out.writeBytes(m.getData());
        }
    }

}
package com.codec;

import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

public class MsgDecode extends ByteToMessageDecoder {

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        while(true){
            if (in.readableBytes() < 4)
                return;

            in.markReaderIndex();
            int total = in.readInt();
            if (in.readableBytes() < total){
                in.resetReaderIndex();
                return;
            }

            short cmd = in.readShort();
            byte[] data = new byte[total - 2];
            in.readBytes(data);

            NetMsg m = new NetMsg();
            m.setCmd(cmd);
            m.setData(data);
            out.add(m);
        }
    }

}
package com;

import com.codec.NetMsg;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class ClientHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        NetMsg m = (NetMsg)msg;
        System.out.println("==============from server===========");
        System.out.println(new String(m.getData(), "UTF-8"));
        super.channelRead(ctx, msg);

    }


}
package com;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import com.codec.MsgDecode;
import com.codec.MsgEncode;
import com.codec.NetMsg;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class Client {

    class ClientInitianlizer extends ChannelInitializer<SocketChannel>{

        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pp = ch.pipeline();
            pp.addLast("decoder", new MsgDecode());
            pp.addLast("encoder", new MsgEncode());
            pp.addLast("handler", new ClientHandler());
        }

    }

    public void start(String host, int port) throws InterruptedException, IOException{
        System.out.println("==========>>start client host:" + host + ":" + port + "============");
        EventLoopGroup group = new NioEventLoopGroup();
        try{

            Bootstrap b = new Bootstrap();
            b.group(group);
            b.channel(NioSocketChannel.class);
            b.handler(new ClientInitianlizer());
            Channel ch = b.connect(host,  port).sync().channel();

            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            while(true){
                String line = in.readLine();
                if (line == null){
                    continue;
                }

                if (line.contains("quit")){
                    break;
                }

                NetMsg m = new NetMsg();
                m.setCmd((short)100);
                m.setData(line.getBytes());
                ch.writeAndFlush(m);
            }
        }finally{
            group.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        try {
            new Client().start("127.0.0.1", 9001);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
package com;

import com.codec.NetMsg;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class ServerHandler extends ChannelInboundHandlerAdapter{

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        super.channelRead(ctx, msg);
        NetMsg m = (NetMsg)msg;
        System.out.println("==========from client==========");
        System.out.println(new String(m.getData(), "UTF-8"));
        ctx.writeAndFlush(msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }


}
package com;

import com.codec.MsgDecode;
import com.codec.MsgEncode;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class Server {

    class ServerInitializer extends ChannelInitializer<SocketChannel>{

        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline pp = ch.pipeline();
            pp.addLast("decoder", new MsgDecode());
            pp.addLast("encoder", new MsgEncode());
            pp.addLast("handler", new ServerHandler());
        }

    }

    public void start(int port) throws InterruptedException {
        System.out.println("===============start server port:" + port + "=====================");
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup);
            b.channel(NioServerSocketChannel.class);
            b.childHandler(new ServerInitializer());

            ChannelFuture f = b.bind(port).sync();
            f.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        try {
            new Server().start(9001);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

上面完整的代码,编译测试通过

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值