netty创建tcp (使用maven构建)

一、环境

java 版本 1.8.0_181

二、项目结构

项目结构如下图所示


netty创建tcp (使用maven构建)_第1张图片
image.png
三、导入必要的依赖

以下是pom.xml的配置



    4.0.0

    netty_tcp_test
    netty_tcp_test
    1.0-SNAPSHOT

    
        4.1.25.Final
        linux-x86_64
    

    
        
        
            io.netty
            netty-codec
            ${netty.version}
        
        
            io.netty
            netty-transport
            ${netty.version}
        
        
            io.netty
            netty-transport-native-epoll
            ${netty.version}
            ${os.detected.classifier}
        
        
            junit
            junit
            4.12
            test
        
        
            io.netty
            netty-codec-http
            ${netty.version}
        
        
            io.netty
            netty-handler
            ${netty.version}
        
        
            io.netty
            netty-transport-udt
            ${netty.version}
        
        
            io.netty
            netty-transport-sctp
            ${netty.version}
        

    

三、创建客户端代码

TcpClient的 main代码

package tcp;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import org.omg.PortableServer.POA;

public class TcpClient {

    public static String HOST = "127.0.0.1";

    public static int PORT = 12340;

    public static Bootstrap bootstrap=getBootstrap();

    public static Channel channel = getChannel(HOST,PORT);

    public static final Bootstrap getBootstrap(){
        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group).channel(NioSocketChannel.class);
        bootstrap.handler(new ChannelInitializer() {
            @Override
            protected void initChannel(Channel ch) throws Exception{

                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast("frameDecoder",new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
                pipeline.addLast("frameEncoder",new LengthFieldPrepender(4));
                pipeline.addLast(new ObjectEncoder());
                pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
                pipeline.addLast("handler",new TcpClientHandler());
            }
        });
        bootstrap.option(ChannelOption.SO_KEEPALIVE,true);
        return bootstrap;
    }

    public static final Channel getChannel(String HOST, int PORT){
        Channel channel = null;
        try{
            channel = bootstrap.connect(HOST,PORT).sync().channel();
            System.out.println("连接成功");
        }catch (Exception e){
            System.out.println("连接server(IP{},PROT{})失败");
            return null;
        }
        return channel;
    }

    public static void sendMsg(Object msg) throws Exception{
        if(channel!=null){
            channel.writeAndFlush(msg).sync();
        }else{
            System.out.println("消息发送失败,连接尚未建立");
        }
    }

}

处理器TcpClientHandler代码

package tcp;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class TcpClientHandler extends SimpleChannelInboundHandler {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx,Object msg) throws Exception{

    }
}

 
 
四、创建服务端代码

TcpServer服务端的main代码

package tcp;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoop;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import org.omg.CORBA.PUBLIC_MEMBER;

public class TcpServer {

    private static final String IP = "192.168.1.154";
    private static final int PORT = 12340;

    /*处理业务线程的线程组个数*/

    protected static final int BIZGROUPSIZE = Runtime.getRuntime().availableProcessors()*2;//默认

    /*业务出现线程大小*/
    protected static final int BIZTHREADSIZE=4;
    /*
     * NioEventLoopGroup实际上就是个线程池,
     * NioEventLoopGroup在后台启动了n个NioEventLoop来处理Channel事件,
     * 每一个NioEventLoop负责处理m个Channel,
     * NioEventLoopGroup从NioEventLoop数组里挨个取出NioEventLoop来处理Channel
     */
    private static final EventLoopGroup bossGroup = new NioEventLoopGroup(BIZGROUPSIZE);

    private static final EventLoopGroup workerGroup = new NioEventLoopGroup(BIZTHREADSIZE);

    protected static void shutdown(){
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }

    public static void run() throws Exception{
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup,workerGroup);
        b.channel(NioServerSocketChannel.class);
        b.childHandler(new ChannelInitializer() {

            @Override
            public void initChannel(SocketChannel ch) throws Exception{
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast("frameDecoder",new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
                pipeline.addLast("frameEncoder",new LengthFieldPrepender(4));
                pipeline.addLast(new ObjectEncoder());
                pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
                pipeline.addLast(new TcpServerHandler());
            }
        });
        //标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度
        b.option(ChannelOption.SO_BACKLOG,1024);
        //是否启用心跳保或机制
        b.childOption(ChannelOption.SO_KEEPALIVE,true);
        //绑定端口 开启监听
        ChannelFuture channelFuture = b.bind(PORT).sync();
        if(channelFuture.isSuccess()){
            System.out.println(("Tcp服务启动成功---"));
        }
        //获取channel的closeFuture,并且阻塞当前线程直到它完成
        channelFuture.channel().closeFuture().sync();

    }
    public static void main(String[] args) throws Exception{
        TcpServer.run();
    }
}

创建TcpServerHandler处理器代码

package tcp;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;

public class TcpServerHandler extends SimpleChannelInboundHandler {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx,Object msg) throws Exception{
        System.out.println("server received:"+msg.toString());
        ctx.write(msg);
    }

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

}

 
 
五、单元测试代码

客户端单元测试TcpClientTest

package tcp;

import org.junit.Test;

import static org.junit.Assert.*;

public class TcpClientTest {

    @Test
    public void sendMsg() {
        try{
            TcpClient.sendMsg("henhao");
        }catch (Exception e){

        }

    }
}

服务端单元测试 TcpServerTest

package tcp;

import org.junit.Test;

import static org.junit.Assert.*;

public class TcpServerTest {

   public static void main(String[] args){
       start();
   }

   @Test
   public void testServer(){
       start();
   }

   public static void start(){
       try{
           TcpServer.main(null);
       }catch (Exception e){

       }

   }
}

你可能感兴趣的:(netty创建tcp (使用maven构建))