概要
初学netty,针对客户端与服务端引导(加载)阶段区别进行对比分析。
代码
服务端
代码:
public class EchoServer {
private final int port;
public EchoServer(int port) {
this.port = port;
}
public static void main(String[] args)
throws Exception {
if (args.length != 1) {
System.err.println("Usage: " + EchoServer.class.getSimpleName() +
" <port>"
);
return;
}
int port = Integer.parseInt(args[0]);
new EchoServer(port).start();
}
public void start() throws Exception {
final EchoServerHandler serverHandler = new EchoServerHandler();
EventLoopGroup group = new NioEventLoopGroup();
try {
- ServerBootstrap b = new ServerBootstrap();
- b.group(group)
- .channel(NioServerSocketChannel.class)
- .localAddress(new InetSocketAddress(port))
- .childHandler(new ChannelInitializer<SocketChannel>() {
- @Override
- public void initChannel(SocketChannel ch) throws Exception {
- ch.pipeline().addLast(serverHandler);
- }
- });
- ChannelFuture f = b.bind().sync();
System.out.println(EchoServer.class.getName() +
" started and listening for connections on " + f.channel().localAddress());
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
}
客户端
代码:
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 Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
- Bootstrap b = new Bootstrap();
- b.group(group)
- .channel(NioSocketChannel.class)
- .remoteAddress(new InetSocketAddress(host, port))
- .handler(new ChannelInitializer<SocketChannel>() {
- @Override
- public void initChannel(SocketChannel ch)
- throws Exception {
- ch.pipeline().addLast(new EchoClientHandler());}
- });
- ChannelFuture f = b.connect().sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
public static void main(String[] args)
throws Exception {
if (args.length != 2) {
System.err.println("Usage: " + EchoClient.class.getSimpleName() +
" <host> <port>"
);
return;
}
final String host = args[0];
final int port = Integer.parseInt(args[1]);
new EchoClient(host, port).start();
}
}
分析
第一部分代码是服务端代码,第二部分是客户端代码,现在对标红部分逐行分析:
1. Netty的引导类提供两种引导类型,客户端(Bootstrap)-用于连接到远程主机和端口,服务端(ServerBootstrap)-用于绑定服务端主机的一个端口。
2.对引导类对象进行绑定EventLoopGroup, 示例代码中服务端与客户端都绑定了一个group,b.group(group)。在实际开发中,通常引导客户端需要一个EventLoopGroup,而ServerBootstrap需要两个EventLoopGroup,创建两个EventLoopGroup对象parentGroup和childGroup,然后b.group(parentGroup,childGroup)来引导服务端。parentGroup只包含一个SocketChannel(第五行中的参数),是服务端用来绑定服务端主机的监听端口。childGroup是实际用来处理客户端连接的请求的。
3.指定传输的channel类型为NIO,也可以指定为OIO。
4.服务端使用localAddress来指定服务器主机的监听端口,客户端使用remoteAddress指定需要连接的远程服务端主机地址及端口号。
5-10.服务端使用.childHandler将handler(处理逻辑)添加到pipeline中,客户端使用.handler添加。
11.服务端使用.bind绑定创建一个ChannelFuture对象用来监听channel的事件,客户端使用.connect创建 ChannelFuture。
总结
以上为个人学习过程中理解总结,错误之处望帮忙指出。
参考书籍:《Netty实战》 ----- 何品 译