netty-discardServer

本文介绍了如何使用Netty实现一个服务器,该服务器在接收到客户端数据时忽略接收到的数据,遵循DISCARD协议。Netty的ChannelFactory负责创建和管理渠道资源,而Bootstrap是服务器配置助手,用于设置管道和处理新连接。在配置管道时,我们可以添加自定义处理器。文章还讨论了如何设置TCP/IP服务器的特定选项,如套接字选项。最后,通过调用bind方法启动服务器监听所有网络接口卡的端口。
摘要由CSDN通过智能技术生成
package org.jboss.netty.example.discard;

public class DiscardServerHandler extends SimpleChannelHandler {1

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {2
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {3
        e.getCause().printStackTrace();
        
        Channel ch = e.getChannel();
        ch.close();
    }
}

DiscardServerHandler extends SimpleChannelHandler, which is an implementation of ChannelHandler. SimpleChannelHandler provides various event handler methods that you can override. For now, it is just enough to extend SimpleChannelHandler rather than to implement the handler interfaces by yourself.

We override the messageReceived event handler method here. This method is called with aMessageEvent, which contains the received data, whenever new data is received from a client. In this example, we ignore the received data by doing nothing to implement the DISCARD protocol.

exceptionCaught event handler method is called with anExceptionEvent when an exception was raised by Netty due to I/O error or by a handler implementation due to the exception thrown while processing events. In most cases, the caught exception should be logged and its associated channel should be closed here, although the implementation of this method can be different depending on what you want to do to deal with an exceptional situation. For example, you might want to send a response message with an error code before closing the connection.


package org.jboss.netty.example.discard;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

public class DiscardServer {

    public static void main(String[] args) throws Exception {
        ChannelFactory factory =
            new NioServerSocketChannelFactory1(
                    Executors.newCachedThreadPool(),
                    Executors.newCachedThreadPool());

        ServerBootstrap bootstrap = new ServerBootstrap2(factory);

        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {3
            public ChannelPipeline getPipeline() {
                return Channels.pipeline(new DiscardServerHandler());
            }
        });

        bootstrap.setOption("child.tcpNoDelay", true);4
        bootstrap.setOption("child.keepAlive", true);

        bootstrap.bind(new InetSocketAddress(8080));5
    }
}

ChannelFactory is a factory which creates and managesChannels and its related resources. It processes all I/O requests and performs I/O to generateChannelEvents. Netty provides various ChannelFactory implementations. We are implementing a server-side application in this example, and thereforeNioServerSocketChannelFactory was used. Another thing to note is that it does not create I/O threads by itself. It is supposed to acquire threads from the thread pool you specified in the constructor, and it gives you more control over how threads should be managed in the environment where your application runs, such as an application server with a security manager.

ServerBootstrap is a helper class that sets up a server. You can set up the server using aChannel directly. However, please note that this is a tedious process and you do not need to do that in most cases.

Here, we configure the ChannelPipelineFactory. Whenever a new connection is accepted by the server, a newChannelPipeline will be created by the specifiedChannelPipelineFactory. The new pipeline contains theDiscardServerHandler. As the application gets complicated, it is likely that you will add more handlers to the pipeline and extract this anonymous class into a top level class eventually.

You can also set the parameters which are specific to the Channel implementation. We are writing a TCP/IP server, so we are allowed to set the socket options such astcpNoDelay and keepAlive. Please note that the"child." prefix was added to all options. It means the options will be applied to the acceptedChannels instead of the options of the ServerSocketChannel. You could do the following to set the options of theServerSocketChannel:

bootstrap.setOption("reuseAddress", true);

We are ready to go now. What's left is to bind to the port and to start the server. Here, we bind to the port8080 of all NICs (network interface cards) in the machine. You can now call thebind method as many times as you want (with different bind addresses.)


*****
ChannelFactory生产和管理所有渠道和渠道相关资源,并且处理所有io请求, 将io请求封装成ChannelEvents。另外需要注意ChannelFactory并不会自主创建线程对象。它从线程池中获取线程。 而线程池中的线程则根据传入的参数来确定。

例如NioServerSocketChannelFactory 有两个构造方法, 一个参数为(Executor bossExecutor, Executor workerExecutor), 一个为(Executor bossExecutor, Executor workerExecutor, int workerCount)其中workerCount就是线程数。第一个构造方法中没有传入workerCount则默认回去取cpu可以支持的最大线程数,再乘以2。

public NioServerSocketChannelFactory(
            Executor bossExecutor, Executor workerExecutor) {
        this(bossExecutor, workerExecutor, SelectorUtil.DEFAULT_IO_THREADS);
    }

static final int DEFAULT_IO_THREADS = Runtime.getRuntime().availableProcessors() * 2;
这里有一点需要注意, 我的机器是thinkpad420, 处理器个数为2, 但是支持超线程, 最大线程数可以达到4,所以在我机器上DEFAULT_IO_THREADS的值为8。

*******
为bootstrap添加了channelFactory后, 每次服务端接收到客户端的连接请求, 都会创建相应的管道pipeline, 这个管道中包含了我们自定义的用来处理客户端请求的handler。

bootstrap.setOption 方法的key值如果是为接入的客户端渠道设置属性则需要加上“child.”前缀, 如果没有这个前缀,则属性就是为服务端ServerSocketChannel设置的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值