使用netty编写客户端,实现同步发送消息并接收返回结果

使用netty编写客户端,实现同步发送消息并接收返回结果

描述

在网上找了很久都没有找到自己想要的代码,今天就自己研究了一下,使用了CountDownLatch实现了发送之后可以接收返回结果。

服务端

MyServerNetty

package com.chen.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class MyServerNetty {
    private int port;

    public MyServerNetty(int port) {
        this.port = port;
    }

    public void action(){
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        try{
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            ((ServerBootstrap)((ServerBootstrap)((ServerBootstrap)serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)).option(ChannelOption.SO_BACKLOG, 128)).childOption(ChannelOption.SO_KEEPALIVE, true).handler(new LoggingHandler(LogLevel.INFO))).childHandler(new ChannelInitializer<SocketChannel>() {
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    socketChannel.pipeline().addLast(new ChannelHandler[]{new MyServerHandler()});
                }
            });
            System.err.println("server 开启--------------");
            ChannelFuture cf = serverBootstrap.bind(this.port).sync();
            cf.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        (new MyServerNetty(9999)).action();
        System.out.println("main==============>启动服务端");
    }
}

MyServerHandler

package com.chen.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class MyServerHandler extends ChannelInboundHandlerAdapter {

    public MyServerHandler() {
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf byteBuf = (ByteBuf) msg;
        byte[] bytes = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(bytes);
        String msg_str = new String(bytes,"UTF-8");
        System.out.println("===========>接收客户端消息:"+msg_str);
        System.out.println("===========>向客户端发送消息:"+msg_str);
        ctx.writeAndFlush(Unpooled.copiedBuffer(msg_str.getBytes()));
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.err.println("服务端读取数据完毕");
    }

}

客户端

MyNettyClient

package com.chen.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.io.UnsupportedEncodingException;
import java.util.concurrent.CountDownLatch;

public class MyClientNetty {
    public static CountDownLatch countDownLatch = new CountDownLatch(1);
    public static CountDownLatch countDownLatch2 = new CountDownLatch(1);
    private String ip;
    private int port;
    private static ChannelFuture cf;
    private static EventLoopGroup bossGroup;

    public MyClientNetty(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }

    public String sendRecv(String msg){
        try {
            cf.channel().writeAndFlush(Unpooled.copiedBuffer(msg.getBytes()));
            MyClientNetty.countDownLatch.await();
            return MyClientHandler.message;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void connect() throws UnsupportedEncodingException, InterruptedException {
        this.action();
        countDownLatch2.await();
    }

    public void close() throws InterruptedException {
        cf.channel().closeFuture().sync();
        bossGroup.shutdownGracefully();
    }

    public void action() throws InterruptedException, UnsupportedEncodingException {
        bossGroup = new NioEventLoopGroup();
        final Bootstrap bs = new Bootstrap();

        ((Bootstrap)((Bootstrap)((Bootstrap)((Bootstrap)bs.group(bossGroup)).channel(NioSocketChannel.class)).option(ChannelOption.SO_KEEPALIVE, true)).option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))).handler(new ChannelInitializer<SocketChannel>() {
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                socketChannel.pipeline().addLast(new ChannelHandler[]{new MyClientHandler()});
            }
        });

        (new Thread(new Runnable() {
            public void run() {
                try {
                    MyClientNetty.cf = bs.connect(MyClientNetty.this.ip, MyClientNetty.this.port).sync();
                    MyClientNetty.countDownLatch2.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        })).start();
    }

    public static void main(String[] args) {

        try {
            MyClientNetty myClientNetty = new MyClientNetty("127.0.0.1",9999);
            myClientNetty.connect();
            String result = myClientNetty.sendRecv("hello world");
            System.out.println(result);
            myClientNetty.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

MyNettyHandler

package com.chen.netty;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class MyClientHandler extends ChannelInboundHandlerAdapter {
    public static String message;

    public MyClientHandler() {
    }

    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            ByteBuf byteBuf = (ByteBuf)msg;
            byte[] bytes = new byte[byteBuf.readableBytes()];
            byteBuf.readBytes(bytes);
            message = new String(bytes);
            MyClientNetty.countDownLatch.countDown();
        } finally {
            ReferenceCountUtil.release(msg);
        }

    }

    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.err.println("客户端读取数据完毕");
        ctx.close();
    }

    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.err.println("client 读取数据出现异常");
        ctx.close();
    }
}

总结

代码直接复制,运行,然后自己跟踪一下。

你可能感兴趣的:(java,netty,java)