练习
实现一个 echo Server
编写服务端:
/**
* @desc
* @auth llp
* @date 2022/8/8 15:19
*/
public class EchoServer {
public static void main(String[] args) {
new ServerBootstrap()
.group(new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// 入站处理器
ch.pipeline().addLast("readHandler", new ChannelInboundHandlerAdapter(){
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// 思考:是否需要 buf 释放?
ByteBuf buf = msg instanceof ByteBuf ? (ByteBuf) msg : null;
if (buf != null){
System.out.println(buf.toString(Charset.defaultCharset()));
buf.release();
}else {
System.out.println("null");
}
// 建议使用 ctx.alloc() 创建 ByteBuf
ByteBuf response = ctx.alloc().buffer();
response.writeBytes("hello I am Server.".getBytes());
ctx.writeAndFlush(response);
// 思考:response 是否需要释放
response.release();
}
});
}
})
.bind(8888);
}
}
编写客户端:
/**
* @desc
* @auth llp
* @date 2022/8/8 15:25
*/
public class EchoClient {
public static void main(String[] args) throws InterruptedException {
ChannelFuture channelFuture = new Bootstrap()
.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
@Override // 建立连接后触发
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ByteBuf buf = ctx.alloc().buffer(10);
// 首次连接发送 hello
buf.writeBytes("hello I am Client.".getBytes());
ctx.writeAndFlush(buf);
// 思考:是否需要释放 buf
buf.release();
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// 思考:是否需要 buf 释放?
ByteBuf buf = msg instanceof ByteBuf ? (ByteBuf) msg : null;
if (buf != null){
System.out.println(buf.toString(Charset.defaultCharset()));
buf.release();
}else {
System.out.println("null");
}
}
});
}
})
.connect("localhost", 8888);
}
}
Java Socket 是全双工的,线路上存在
A 到 B
和B 到 A
的双向信号传输,即时是阻塞 IO,读和写是可以同时进行的,只要分别采用读线程和写线程即可,读不会阻塞写、写也不会阻塞读。