Open xiwenAndlejian opened 5 years ago
本文内容:创建一个 EchoServer(回声服务),并使用 telnet 测试。
EchoServer:将接受的数据不做任何处理,直接返回给客户端
public class EchoServerDemo { public static void main(String[] args) throws InterruptedException { NioEventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(group) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) throws Exception { ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // 将从客户端接收到的消息回写给客户端 ctx.writeAndFlush(msg); } }); } }); // 绑定(侦听)8000端口 ChannelFuture future = bootstrap.bind(8000).sync(); future.channel().closeFuture().sync(); } finally { // 释放资源 group.shutdownGracefully(); } } }
启动结果
终端中执行命令telnet 127.0.0.1 8000 如下所示表示已连接上服务端:
telnet 127.0.0.1 8000
$telnet 127.0.0.1 8000 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'.
此时输入内容,并按下回车发送消息给服务端:
hello # telnet 发送的消息 hello # server 回复的消息 echo # telnet 发送的消息 echo # server 回复的消息
注:也可以使用多个 telnet 进程连接客户端,测试消息回传是单播还是广播。
这大概是最简单的服务端代码了。
服务端主要功能:服务端不对上传的数据进行任何处理,直接将上传数据回写给客户端。 这段主要功能对应的代码:
new ChannelInboundHandlerAdapter(){ @Override public void channelRead(ChannelHandlerContext ctx,Object msg)throws Exception{ // 将从客户端接受到的消息回写给客户端 ctx.writeAndFlush(msg); } }
channelRead :将在 channel 有数据可读时触发。 ctx.writeAndFlush():将消息写入并且立即刷新缓存,此处类似于 JDK 中的 I/O 流,消息并不会立即发送,而是存放在缓存区,刷新后才立即写入。 这段匿名内部类实际是创建一个处理回写业务的 ChannelHandler,当有数据可读时,立即回写该数据。
NioEventLoopGroup group = new NioEventLoopGroup(); try { ... // 绑定(侦听)8000端口 ChannelFuture future = bootstrap.bind(8000).sync(); future.channel().closeFuture().sync(); } finally { // 释放资源 group.shutdownGracefully(); }
暂时只需要明白这一段代码做了几件事:
源码中只剩最后这一段了:
ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(group) .channel(NioServerSocketChannel.class) .childHandler(...)
这一段大致的作用:
EchoServer 与 Client 关系图:
目前 EchoServer 侦听 8000 端口。每与一个 Client (本文中使用的 telnet)建立连接,Server 便会创建一个 channel。并且与一个 EventLoop 绑定,而 EventLoop 本身绑定一个线程,在整个 channel 生命周期中,都会是在该 EventLoop/线程 中处理。 Server 中,与多个 Client 建立的 channel 本身是互不相干的,对其中一个 channel 写入消息并不会影响其他 channel。
注意:写入数据之后需要刷新缓存区才能发送消息。write() 和 flush(),或者直接调用简写方法 writeAndFlush()。
Netty 学习笔记(一)EchoServer
本文内容:创建一个 EchoServer(回声服务),并使用 telnet 测试。
源码
进行测试
1. 启动服务端
启动结果
2. 使用 telnet 连接
终端中执行命令
telnet 127.0.0.1 8000
如下所示表示已连接上服务端:此时输入内容,并按下回车发送消息给服务端:
注:也可以使用多个 telnet 进程连接客户端,测试消息回传是单播还是广播。
源码拆分
这大概是最简单的服务端代码了。
业务代码
服务端主要功能:服务端不对上传的数据进行任何处理,直接将上传数据回写给客户端。 这段主要功能对应的代码:
channelRead :将在 channel 有数据可读时触发。 ctx.writeAndFlush():将消息写入并且立即刷新缓存,此处类似于 JDK 中的 I/O 流,消息并不会立即发送,而是存放在缓存区,刷新后才立即写入。 这段匿名内部类实际是创建一个处理回写业务的 ChannelHandler,当有数据可读时,立即回写该数据。
端口&资源的释放
暂时只需要明白这一段代码做了几件事:
服务端引导器
源码中只剩最后这一段了:
这一段大致的作用:
EchoServer 总结
EchoServer 与 Client 关系图:
目前 EchoServer 侦听 8000 端口。每与一个 Client (本文中使用的 telnet)建立连接,Server 便会创建一个 channel。并且与一个 EventLoop 绑定,而 EventLoop 本身绑定一个线程,在整个 channel 生命周期中,都会是在该 EventLoop/线程 中处理。 Server 中,与多个 Client 建立的 channel 本身是互不相干的,对其中一个 channel 写入消息并不会影响其他 channel。
注意:写入数据之后需要刷新缓存区才能发送消息。write() 和 flush(),或者直接调用简写方法 writeAndFlush()。