3、netty第二个例子,使用netty建立客户端,与服务端通讯

第一个例子中,建立了http的服务器端,可以直接使用curl命令,或者浏览器直接访问。

在第二个例子中,建立一个netty的客户端来主动发送请求,模拟浏览器发送请求。

这里先启动服务端,再启动客户端,启动客户端后,在 channelActive 方法中,主动向服务器端发送消息,服务器端channelRead0 方法中,接收到客户端的消息后,会再向客户端返回消息。客户端channelRead0方法中接收到消息再向客户端发送消息,依次往复。

同样的,按照顺序

 

client

 1 import io.netty.bootstrap.Bootstrap;
 2 import io.netty.channel.ChannelFuture;
 3 import io.netty.channel.EventLoopGroup;
 4 import io.netty.channel.nio.NioEventLoopGroup;
 5 import io.netty.channel.socket.nio.NioServerSocketChannel;
 6 import io.netty.channel.socket.nio.NioSocketChannel;
 7 
 8 public class MyClient {
 9     public static void main(String[] args) throws InterruptedException {
10         //客户端只需要一个
11         EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
12 
13         try{
14 
15             Bootstrap bootstrap = new Bootstrap();
16             bootstrap.group(eventLoopGroup)
17                     .channel(NioSocketChannel.class)
18                     .handler(new MyClientInitlalizer());
19             ChannelFuture channelFuture = bootstrap.connect("localhost", 8899).sync();
20 
21             //channelFuture.channel().writeAndFlush("first msg");//发送数据,其实应该写到handler的active方法中
22 
23             channelFuture.channel().closeFuture().sync();
24 
25         }finally {
26             eventLoopGroup.shutdownGracefully();
27         }
28 
29     }
30 }

 

Initlalizer

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

public class MyClientInitlalizer extends ChannelInitializer {

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline channelPipeline = ch.pipeline();

        //添加解码器的handler
        channelPipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));

        channelPipeline.addLast(new LengthFieldPrepender(4));
        //字符串的解码器
        channelPipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
        //字符串的编码器
        channelPipeline.addLast( new StringEncoder(CharsetUtil.UTF_8));
        //自定义的处理器
        channelPipeline.addLast(new MyClientHandler());
    }
}

 

handler

 1 import io.netty.channel.ChannelHandlerContext;
 2 import io.netty.channel.SimpleChannelInboundHandler;
 3 
 4 import java.time.LocalDateTime;
 5 
 6 public class MyClientHandler  extends SimpleChannelInboundHandler {
 7     @Override
 8     protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
 9         System.out.println( ctx.channel().remoteAddress() + "," + msg);
10         System.out.println( "client output:" + msg);
11 
12         ctx.writeAndFlush("from client" + LocalDateTime.now());
13     }
14 
15     @Override
16     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
17         cause.printStackTrace();
18         ctx.close();
19         //super.exceptionCaught(ctx, cause);
20     }
21 
22     @Override
23     public void channelActive(ChannelHandlerContext ctx) throws Exception {
24         ctx.channel().writeAndFlush("来自客户端的问候!");//通道连接之后,发送数据
25         super.channelActive(ctx);
26     }
27 }

 

sever中的handle

server中的server代码和第一个例子类似,initlializer和client中的一致,就不贴代码了。

public class MyServerHandler extends SimpleChannelInboundHandler {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println(ctx.channel().remoteAddress() + "," + msg);

        ctx.writeAndFlush("from serevber" + UUID.randomUUID());//消息返回
    }

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

 

你可能感兴趣的:(3、netty第二个例子,使用netty建立客户端,与服务端通讯)