netty入门文章2

文章目录

1、netty4.x

2、netty实例

 

正文部分

1、netty4.x

原文:

The minimum requirements to run the examples which are introduced in this chapter are only two;

the latest version of Netty and JDK 1.6 or above.

The latest version of Netty is available in the project download page.

To download the right version of JDK, please refer to your preferred JDK vendor's web site.

要点:

a.演示例子里边使用的是netty4.x最新版本的架包。

b.JDK1.6或者1.6以上版本。

下载地址:

http://netty.io/Main/Downloads

http://www.oracle.com/technetwork/java/javase/downloads/index.html

2、netty实例

2.1、Writing a Discard Server  抛弃协议

原文:

http://tools.ietf.org/html/rfc863  Discard Protocol协议

A useful debugging and measurement tool is a discard service. A discard service simply throws away any data it receives.

要点:

a.接收到什么抛弃什么,它对调试网络状态有一定的用处。

b.服务器就会在TCP端口9检测抛弃协议请求,在建立连接后并检测到请求后,就直接把接收到的数据直接抛弃,直到用户中断连接。

c.UDP协议类似TCP的方式,端口也是9。

代码如下:

DiscardServerHandler 业务处理handler类

代码要点:

a.handler继承ChannelInboundByteHandlerAdapter方式来实现,实在要实现handler接口实现也是OK的。

b.覆写inboundBufferUpdated方法,ByteBuf携带从client发送过来的数据,调用基于抛弃协议实现的clear方法。

c.exceptionCaught方法在出现异常时候执行,比如可以发送一条错误消息到client端。

DiscardServerHandler
 1 package io.netty.example.discard;  2 
 3 import io.netty.buffer.ByteBuf;  4 import io.netty.channel.ChannelHandlerContext;  5 import io.netty.channel.ChannelInboundByteHandlerAdapter;  6 
 7 import java.util.logging.Level;  8 import java.util.logging.Logger;  9 
10 /**
11  * Handles a server-side channel. 12  */
13 public class DiscardServerHandler extends ChannelInboundByteHandlerAdapter { 14 
15     private static final Logger logger = Logger.getLogger( 16             DiscardServerHandler.class.getName()); 17 
18  @Override 19     public ByteBuf newInboundBuffer(ChannelHandlerContext ctx) throws Exception { 20         // Use direct buffer if possible. 21         // If you are going to use a heap buffer, you don't need to override this method.
22         return ctx.alloc().ioBuffer(); 23  } 24 
25  @Override 26     public void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf in) 27             throws Exception { 28     while(in.readable()){ 29         System.out.println((char)in.readByte());  // 将内容打印出来,方便调式而已
30  System.out.flush(); 31  } 32         // Discard the received data silently.
33  in.clear(); 34  } 35 
36  @Override 37     public void exceptionCaught(ChannelHandlerContext ctx, 38             Throwable cause) throws Exception { 39         // Close the connection when an exception is raised.
40  logger.log( 41  Level.WARNING, 42                 "Unexpected exception from downstream.", 43  cause); 44  ctx.close(); 45  } 46 }

代码如下:

DiscardServer 抛弃协议服务器端代码

要点:

netty4.x比起netty3.x做了一些变化

DiscardServer
 1 package io.netty.example.discard;  2 
 3 import io.netty.bootstrap.ServerBootstrap;  4 import io.netty.channel.ChannelFuture;  5 import io.netty.channel.ChannelInitializer;  6 import io.netty.channel.socket.SocketChannel;  7 import io.netty.channel.nio.NioEventLoopGroup;  8 import io.netty.channel.socket.nio.NioServerSocketChannel;  9 
10 /**
11  * Discards any incoming data. 12  */
13 public class DiscardServer { 14 
15     private final int port;  // 服务器绑定的tcp端口号
16 
17     public DiscardServer(int port) { 18         this.port = port; 19  } 20 
21     public void run() throws Exception { 22         ServerBootstrap b = new ServerBootstrap(); // netty server端启动类
23         try { 24         // netty4.x和3.x的变化地方,提供各种EventLoopGroup实现类来支持各种传输协议。
25             b.group(new NioEventLoopGroup(), new NioEventLoopGroup()) // 第一个loop负责接收request,第二个负责处理perform。
26              .channel(NioServerSocketChannel.class) 27              .childHandler(new ChannelInitializer<SocketChannel>() { 28  @Override 29                 public void initChannel(SocketChannel ch) throws Exception { 30                     ch.pipeline().addLast(new DiscardServerHandler());  // server和client创建成功一个connection后会call这个方法。
31  } 32  }); 33 
34             // server绑定在某个端口,等待client的连接
35             ChannelFuture f = b.bind(port).sync(); 36 
37             // Wait until the server socket is closed. 38             // In this example, this does not happen, but you can do that to gracefully 39             // shut down your server.
40  f.channel().closeFuture().sync(); 41         } finally { 42  b.shutdown(); 43  } 44  } 45 
46     public static void main(String[] args) throws Exception { 47         int port; 48         if (args.length > 0) { 49             port = Integer.parseInt(args[0]); 50         } else { 51             port = 8080; 52  } 53         new DiscardServer(port).run(); 54  } 55 }

通过telnet localhost 8080来测试下代码运行性,server端代码稍等改下。

其他client端口见netty包里提供的例子代码。

2.2、Writing an Echo Server 应答协议

原文:

Echo Protocol https://tools.ietf.org/html/rfc862

A very useful debugging and measurement tool is an echo service. An echo service simply sends back to the originating source any data it receives.

要点:

a.类似抛弃协议应答协议也是一个调式的工具服务协议。

b.echo服务协议是将接收到的内容返回给发送方。

c.基于TCP/UDP协议都有实现,同在端口7中监听。

代码如下:

EchoServerHandler 服务器端业务处理handler类

EchoServerHandler
 1 package io.netty.example.echo;  2 
 3 import io.netty.buffer.ByteBuf;  4 import io.netty.channel.ChannelHandler.Sharable;  5 import io.netty.channel.ChannelHandlerContext;  6 import io.netty.channel.ChannelInboundByteHandlerAdapter;  7 
 8 import java.util.logging.Level;  9 import java.util.logging.Logger; 10 
11 /**
12  * Handler implementation for the echo server. 13  */
14 @Sharable 15 public class EchoServerHandler extends ChannelInboundByteHandlerAdapter { 16 
17     private static final Logger logger = Logger.getLogger( 18             EchoServerHandler.class.getName()); 19 
20  @Override 21     public ByteBuf newInboundBuffer(ChannelHandlerContext ctx) throws Exception { 22         // Use direct buffer if possible. 23         // If you are going to use a heap buffer, you don't need to override this method.
24         return ctx.alloc().ioBuffer(); 25  } 26 
27  @Override 28     public void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf in) { 29         ByteBuf out = ctx.nextOutboundByteBuffer();   // 从ctx中获取outbound发包buffer
30         out.writeBytes(in);  // 将server端接收到的内容又写回到client端去 31     // notify that there is some data to flush out (send) to the remote peer.
32         ctx.flush();  // 触发send content操作
33  } 34 
35  @Override 36     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 37         // Close the connection when an exception is raised.
38         logger.log(Level.WARNING, "Unexpected exception from downstream.", cause); 39  ctx.close(); 40  } 41 }

server端代码如下:

EchoServer
 1 package io.netty.example.echo;  2 
 3 import io.netty.bootstrap.ServerBootstrap;  4 import io.netty.channel.ChannelFuture;  5 import io.netty.channel.ChannelInitializer;  6 import io.netty.channel.ChannelOption;  7 import io.netty.channel.socket.SocketChannel;  8 import io.netty.channel.nio.NioEventLoopGroup;  9 import io.netty.channel.socket.nio.NioServerSocketChannel; 10 import io.netty.handler.logging.LogLevel; 11 import io.netty.handler.logging.LoggingHandler; 12 
13 /**
14  * Echoes back any received data from a client. 15  */

16 public class EchoServer { 17 
18     private final int port; 19 
20     public EchoServer(int port) { 21         this.port = port; 22  } 23 
24     public void run() throws Exception { 25         // Configure the server.
26         ServerBootstrap b = new ServerBootstrap(); 27         try { 28             b.group(new NioEventLoopGroup(), new NioEventLoopGroup()) 29              .channel(NioServerSocketChannel.class) 30              .option(ChannelOption.SO_BACKLOG, 100) 31              .handler(new LoggingHandler(LogLevel.INFO)) 32              .childHandler(new ChannelInitializer<SocketChannel>() { 33  @Override 34                  public void initChannel(SocketChannel ch) throws Exception { 35  ch.pipeline().addLast( 36                              new LoggingHandler(LogLevel.INFO), 37                              new EchoServerHandler()); 38  } 39  }); 40 
41             // Start the server.
42             ChannelFuture f = b.bind(port).sync(); 43 
44             // Wait until the server socket is closed.
45  f.channel().closeFuture().sync(); 46         } finally { 47             // Shut down all event loops to terminate all threads.
48  b.shutdown(); 49  } 50  } 51 
52     public static void main(String[] args) throws Exception { 53         int port; 54         if (args.length > 0) { 55             port = Integer.parseInt(args[0]); 56         } else { 57             port = 8080; 58  } 59         new EchoServer(port).run(); 60  } 61 }

client端代码类似抛弃协议中的client,具体查看源代码即可。

2.3、Writing a Time Server 时间同步协议

原文:

This protocol provides a site-independent, machine readable date and time.

The Time service sends back to the originating source the time in seconds since midnight on January first 1900.

要点:

a.client端和server端time同步协议。

b.基于TCP,UDP都有相应的实现。

TCP实现如下:

=============================

S:服务器在37端口监听。

U:用户connect连接到37端口。

S:发送32位数字。

U:接收数字time。

S:关闭connection。

U:关闭连接。

UDP时间见链接:http://tools.ietf.org/html/rfc868

新版本包里居然没有time的演示代码,有点奇怪。待定。

 

你可能感兴趣的:(netty)