Netty Learning [1]: Sending Strings

1 Introduction

Netty is a network application framework based on Java NIO.
Netty is a NIO client-server (client server) framework. Netty can be used to quickly develop network applications, such as server and client protocols. Netty provides a new way to develop network applications that makes it easy to use and highly extensible. Netty's internal implementation is complex, but Netty provides an easy-to-use API to decouple business logic from network processing code. Netty is completely implemented based on NIO, so the entire Netty is asynchronous.
Network applications usually require high scalability, whether Netty or other Java NIO-based frameworks will provide scalable solutions. A key component of Netty is its asynchronous nature.

2. demo instance

2.1, pom file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>tj.cmcc.org</groupId>
  <artifactId>netty.rpc</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>netty.rpc Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
    <dependency>
      <groupId>io.netty</groupId>
      <artifactId>netty-all</artifactId>
      <version>4.1.6.Final</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>netty.rpc</finalName>
  </build>
</project>

 

2.2, server side

EchoServer.java

package hello_netty.server;

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


/**
 * Server startup class
 * • Configure server functions such as threads, ports
 * • Implement a server handler, which contains business logic that decides what to do when there is a request to connect or receive data
 * Created by tianjun on 2016/12/19 0019.
 */
public class EchoServer {

    private final int port;

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

    public void start() throws Exception{

        EventLoopGroup eventLoopGroup = null;
        try {
            //Create an instance of ServerBootstrap to bootstrap the binding and start the server
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            //Create a NioEventLoopGroup object to handle events, such as accepting new connections, receiving data, writing data, etc.
            eventLoopGroup = new NioEventLoopGroup();
            //Specify the channel type as NioServerSocketChannel, set the InetSocketAddress to let the server listen to a port and wait for the client to connect.
            final ServerBootstrap serverBootstrap1 = serverBootstrap.group(eventLoopGroup).channel(NioServerSocketChannel.class)
                    .localAddress("localhost", port).childHandler(new ChannelInitializer<Channel>() {
                        //Set childHandler to execute all connection requests
                        @Override
                        protected void initChannel(Channel ch) {
                            ch.pipeline().addLast(new EchoServerHandler());
                        }
                    });
            // Finally, the binding server waits until the binding is completed, calling the sync() method will block until the server completes the binding, and then the server waits for the channel to close, because the use of sync(), the closing operation will also be blocked.
            ChannelFuture channelFuture = serverBootstrap.bind().sync();
            System.out.println("Start listening, the port is: "+channelFuture.channel().localAddress());
            channelFuture.channel().closeFuture().sync();
        }finally {
            eventLoopGroup.shutdownGracefully().sync();
        }

    }

    public static void main(String[] args) throws Exception {
        new EchoServer(20000).start();
    }
}

 EchoServerHandler.java

package hello_netty.server;

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

import java.io.UnsupportedEncodingException;
import java.util.Date;

/**
 * Server callback method
 * Created by tianjun on 2016/12/19 0019.
 */
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx,Object msg) throws UnsupportedEncodingException {
        System.out.println("server reads data...");
        //read data
        ByteBuf buf = (ByteBuf) msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println("Receive client data: " + body);
        // write data to client
        System.out.println("server sends data to client");
        String currentTime = new Date(System.currentTimeMillis()).toString();
        ByteBuf resp = Unpooled.copiedBuffer(currentTime.getBytes());
        ctx.write(resp);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx){
        System.out.println("server finished reading data..");
        ctx.flush();//The data is sent to SocketChannel after refresh

    }

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

    }
}

 

2.3. Client

EchoClient.java

package hello_netty.client;

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

import java.net.InetSocketAddress;

/**
 * Client startup class
 * • connect to the server
 * • Write data to server
 * • Wait for the accepting server to return the same data
 * • close the connection
 * Created by tianjun on 2016/12/19 0019.
 */
public class EchoClient {
    private final String host;
    private final int port;

    public EchoClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() throws InterruptedException {
        EventLoopGroup nioEventLoopGroup = null;
        try {

            //Create a Bootstrap object to bootstrap the client
            Bootstrap bootstrap = new Bootstrap();
            //Create an EventLoopGroup object and set it to Bootstrap. EventLoopGroup can be understood as a thread pool, which is used to process connections, receive data, and send data
            nioEventLoopGroup = new NioEventLoopGroup();
            //Create InetSocketAddress and set it to Bootstrap, InetSocketAddress is the server address of the specified connection
            bootstrap.group(nioEventLoopGroup).channel(NioSocketChannel.class).remoteAddress(new InetSocketAddress(host, port))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        //Add a ChannelHandler, which will be executed after the client successfully connects to the server
                        @Override
                        protected void initChannel(SocketChannel ch)
                                throws Exception {
                            ch.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            // • Call Bootstrap.connect() to connect to the server
            ChannelFuture f = bootstrap.connect().sync();
            // • Finally close EventLoopGroup to release resources
            f.channel().closeFuture().sync();
        }finally {
            nioEventLoopGroup.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new EchoClient("localhost", 20000).start();
    }

}

 EchoClientHandler.java

package hello_netty.client;

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

/**
 * Client callback method
 * Created by tianjun on 2016/12/19 0019.
 */
public class EchoClientHandler extends SimpleChannelInboundHandler {

    // Called after the client connects to the server
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("The client connects to the server and starts sending data...");
        byte[] req = "QUERY TIME ORDER".getBytes();
        ByteBuf firstMessage = Unpooled.buffer(req.length);
        firstMessage.writeBytes(req);
        ctx.writeAndFlush(firstMessage);
    }

    //• Called when data is received from the server
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object o) throws Exception {

        System.out.println("client reads server data..");
        //After the server returns the message
        ByteBuf buf = (ByteBuf) o;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        String body = new String(req, "UTF-8");
        System.out.println("The server data is: " + body);

    }

    //• Called when an exception occurs
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("client exceptionCaught..");
        // release resources
        ctx.close();
    }

}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326164520&siteId=291194637