入门代码四块:
服务端,服务端的handler,客户端,客户端的handler。
服务端和客户端建立连接后,读写数据是handler完成。理解成业务层分离。
服务端代码:
- 创建两个线程组
NioEventLoopGroup work = new NioEventLoopGroup();
NioEventLoopGroup boss = new NioEventLoopGroup();
这两个线程理解成两组Ractor线程组,一组用于监听端口,一组用于网络读写。从而实现异步。
- 获得一个启动类
ServerBootstrap b = new ServerBootstrap()
- 使用启动类进行设置
b.group(boss, work)
//设置channel为NIO的socketChannel
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new severhandler());
}
}
);
//监听端口,这里是可以作为异步回掉的通知
ChannelFuture future;
future = b.bind(8080).sync();
总结:
1:创建两个线程组,
2:创建一个启动类,
3:使用启动类设置,
加入两个线程组,
设置channel是NioServerSocketChannel,
设置一个childhandler,并添加处理器。
启动类,绑定监听端口。得到ChannelFuture作为异步回掉通知。
服务端handler:
- 继承了ChannelHandlerAdapter用于网络读写
severhandler extends ChannelHandlerAdapter
package com.first.handler;
import java.net.SocketAddress;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
public class severhandler extends ChannelHandlerAdapter {
@Override
//读写方法
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
//将消息转为buf
ByteBuf buf=(ByteBuf) msg;
//创建一个buf长度的数组
byte [] requestbyte=new byte[buf.readableBytes()];
buf.readBytes(requestbyte);
String request=new String(requestbyte,"utf-8");
System.out.println(request);
//响应给客户端
byte [] responsebyte="来自服务器的回应".getBytes();
ByteBuf resBuf=Unpooled.copiedBuffer(responsebyte);
ctx.write(resBuf) ;
}
@Override
//读完执行的方法
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
// TODO Auto-generated method stub
super.channelReadComplete(ctx);
ctx.flush();
}
@Override
//捕获异常的方法
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
// TODO Auto-generated method stub
super.exceptionCaught(ctx, cause);
}
}
总结:
1:读写是面向buf进行的。buf.readableBytes()获取缓冲区可读的字节数。
2:buf.readBytes(requestbyte); 是将缓冲区的字节数组,复制到requestbyte数组中。
3:ctx.write(resBuf) 应答消息。将内容写进缓冲区,然后通过ctx.flush();将消息写到SocketChannel中。