http://linugb118.blog.51cto.com/272628/420738
messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
         // Server is supposed to send nothing.  Therefore, do nothing.
     }
   可以看到Discard client不需要接受任何信息
   
 3.连接server
 ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
这里解释一下channelFuture:
在Netty中所有的io操作都是异步的,这也就是意味任何io访问,那么就立即返回处理,并且不能确保
 返回的数据全部完成。因此就出现了channelFuture,channelFuture在传输数据时候包括数据和状态两个
 部分。他只有Uncompleted和Completed
*                                      +---------------------------+
  *                                      | Completed successfully    |
  *                                      +---------------------------+
  *                                 +---->      isDone() = <b>true</b>      |
  * +--------------------------+    |    |   isSuccess() = <b>true</b>      |
  * |        Uncompleted       |    |    +===========================+
  * +--------------------------+    |    | Completed with failure    |
  * |      isDone() = <b>false</b>    |    |    +---------------------------+
  * |   isSuccess() = false    |----+---->   isDone() = <b>true</b>         |
  * | isCancelled() = false    |    |    | getCause() = <b>non-null</b>     |
  * |    getCause() = null     |    |    +===========================+
  * +--------------------------+    |    | Completed by cancellation |
  *                                 |    +---------------------------+
  *                                 +---->      isDone() = <b>true</b>      |
  *                                      | isCancelled() = <b>true</b>      |
  *                                      +---------------------------+
  
  既然netty io是异步的,那么如何知道channel传送完成有两种方式,一种添加监听器
  addListener(ChannelFutureListener) 还有一种直接调用await()方法,这两种方式
  有下面的区别
  监听器:是以事件模式的,因此代码就需要用事件模式的样式去写,相当复杂,但他是non-blocking模式的
  性能方面要比await方法好,而且不会产生死锁情况
  
  await(): 直接方法调用,使用简单,但是他是blocking模式,性能方面要弱而且会产生死锁情况
  
  不要在ChannelHandler 里面调用await(),这是因为通常在channelHandler里的event method是被i/o线程调用的
  (除非ChannelPipeline里面有个ExecutionHandler),那么如果这个时候用await就容易产生死锁。
  
  错误样例:
 
// BAD - NEVER DO THIS
  * {@code @Override}
  * public void messageReceived({@link ChannelHandlerContext} ctx, {@link MessageEvent} e) {
  *     if (e.getMessage() instanceof GoodByeMessage) {
  *         {@link ChannelFuture} future = e.getChannel().close();
  *         future.awaitUninterruptibly();
  *         // Perform post-closure operation
  *         // ...
  *     }
  * }
  *
  正确样例:
 
* // GOOD
  * {@code @Override}
  * public void messageReceived({@link ChannelHandlerContext} ctx, {@link MessageEvent} e) {
  *     if (e.getMessage() instanceof GoodByeMessage) {
  *         {@link ChannelFuture} future = e.getChannel().close();
  *         future.addListener(new {@link ChannelFutureListener}() {
  *             public void operationComplete({@link ChannelFuture} future) {
  *                 // Perform post-closure operation
  *                 // ...
  *             }
  *         });
  *     }
  * }
  
  虽然await调用比较危险,但是你确保不是在一个i/o 线程中调用该方法,毕竟await方法还是很简洁方便的,如果
  调用该方法是在一个i/o 线程,那么就会抛出 IllegalStateException
  
 
await的timeout和i/o timeout区别
  需要注意的是这两个timeout是不一样的, #await(long),#await(long, TimeUnit), #awaitUninterruptibly(long),
  #awaitUninterruptibly(long, TimeUnit) 这里面的timeout也i/o timeout 没有任何关系,如果io timeout,那么
  channelFuture 将被标记为completed with failure,而await的timeout 与future完全没有关系,只是await动作的
  timeout。
  错误代码
   * // BAD - NEVER DO THIS
  * {@link ClientBootstrap} b = ...;
  * {@link ChannelFuture} f = b.connect(...);
  * f.awaitUninterruptibly(10, TimeUnit.SECONDS);
  * if (f.isCancelled()) {
  *     // Connection attempt cancelled by user
  * } else if (!f.isSuccess()) {
  *     // You might get a NullPointerException here because the future
  *     // might not be completed yet.
  *     f.getCause().printStackTrace();
  * } else {
  *     // Connection established successfully
  * }
  *
  正确代码
  * // GOOD
  * {@link ClientBootstrap} b = ...;
  * // Configure the connect timeout option.
  * <b>b.setOption("connectTimeoutMillis", 10000);</b>
  * {@link ChannelFuture} f = b.connect(...);
  * f.awaitUninterruptibly();
  *
  * // Now we are sure the future is completed.
  * assert f.isDone();
  *
  * if (f.isCancelled()) {
  *     // Connection attempt cancelled by user
  * } else if (!f.isSuccess()) {
  *     f.getCause().printStackTrace();
  * } else {
  *     // Connection established successfully
  * }
  
 4.等待或监听数据全部完成
 如: future.getChannel().getCloseFuture().awaitUninterruptibly();
5.释放连接等资源
  bootstrap.releaseExternalResources();
  
 Server:
 1.配置server
ServerBootstrap bootstrap = new ServerBootstrap(
                 new NioServerSocketChannelFactory(
                         Executors.newCachedThreadPool(),
                         Executors.newCachedThreadPool()));
                         
 2.设置pipeFactory
 
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
             public ChannelPipeline getPipeline() throws Exception {
                 return Channels.pipeline(new EchoServerHandler());
             }
         });
     或者
    bootstrap.setPipelineFactory(new HttpServerPipelineFactory());
    
 3.绑定sever端端口
 
bootstrap.bind(new InetSocketAddress(8080));









