Netty傻瓜教程(一):Netty初探,只寫個服務端也能工做

霸王硬上,直接開始,服務端:java

package com.hengzenc.NettyServer;

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

public class DiscardServerHandler extends ChannelInboundHandlerAdapter {
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg){
		ctx.write(msg);
		ctx.flush();
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
		cause.printStackTrace();ctx.close();
	}

}
  1. DiscardServerHandler繼承了ChannelInboundHandlerAdapter,而不是直接實現父類ChannelInboundHandler,由於ChannelInboundHandlerAdapter已經夠用了。
  2. 咱們覆蓋了channelRead()方法,這個方法在收到信息的時候調用。
  3. 這裏使用的ByteBuf必須進行顯示地進行關閉。
  4. exceptionCaught關閉連接的時候,一般應當首先給客戶端發送一個錯誤消息。

如今咱們用main()方法來啓動DiscardServerHandler的服務器bootstrap

package com.hengzenc.NettyServer;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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 DiscardServer {

    private int port;

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

    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap(); // (2)
            b.group(bossGroup, workerGroup)
             .channel(NioServerSocketChannel.class) // (3)
             .childHandler(new ChannelInitializer<SocketChannel>() { // (4)
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast(new DiscardServerHandler());
                 }
             })
             .option(ChannelOption.SO_BACKLOG, 128)          // (5)
             .childOption(ChannelOption.SO_KEEPALIVE, true); // (6)

            // Bind and start to accept incoming connections.
            ChannelFuture f = b.bind(port).sync(); // (7)

            // Wait until the server socket is closed.
            // In this example, this does not happen, but you can do that to gracefully
            // shut down your server.
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        int port;
        if (args.length > 0) {
            port = Integer.parseInt(args[0]);
        } else {
            port = 8080;
        }
        new DiscardServer(port).run();
    }
}
  1. 咱們在這裏使用了兩個NioEventLoopGroup來處理I/O操做,第一個叫作boss,接收連接請求;第二個叫作worker,在boss接受了請求以後向worker註冊。具體使用多少線程取決於EventLoopGroup的實現。

2.   ServerBootstrap是創建服務器的幫助類。你能夠直接使用Channel來創建服務器。不過請注意這是個無聊的過程,在大多數狀況下不要這樣用。服務器

3.   咱們在這裏使用NioServerSocketChannel來初始新的Channel來接收請求。app

4.   這裏指定的handler常常被新Channel評估。ChannelInitializer是幫助用戶配置新Channel的特定handler。socket

5.   咱們在這裏是實現一個TCP/IP服務器,咱們使用了tcpNoDelay和keepAlive,至於其它的選項,請到ChannelOption和ChannelConfig裏面去查找。tcp

6.   option是給接受請求的NioServerSocketChannel的,childOption是給父ServerChannel接受的Channel,在這裏是NioServerSocketChannel。ide

7.   綁定端口,啓動服務器。oop

上一篇寫好了一個服務器,能夠在本地使用telnet localhost 8080來測試這個服務器,這個服務器只是簡單地回覆你發給它的信息,以下圖所示:測試

相關文章
相關標籤/搜索