BIO\NIO\AIO\Netty简单调用例子

一、同步阻塞IO(BIO)

1.服务端,建立BioServer类

package me.muphy.io.bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class BioServer {
ServerSocket serverSocket;
private String msg;

public BioServer(int port) {
try {
serverSocket = new ServerSocket(port);
System.out.println("服务器已经启动,监听端口是:" + port);
} catch (IOException e) {
e.printStackTrace();
}
}

public void listen() throws IOException {
while (true){
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int len = inputStream.read(buffer);
if (len > 0) {
String msg = new String(buffer, 0, len);
System.out.println("收到:" + msg);
}
}
}

public static void main(String[] args) throws IOException {
new BioServer(8080).listen();
}
}

2.客户端,建立BioClient类
package me.muphy.io.bio;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.UUID;

public class BioClient {
public static void main(String[] args) throws IOException {
Socket client = new Socket("localhost", 8080);
OutputStream outputStream = client.getOutputStream();
String name = UUID.randomUUID().toString();
System.out.println("客户端发送数据:" + name);
outputStream.write(name.getBytes());
outputStream.close();
client.close();
}
}

二、同步非阻塞IO(NIO)

1.客户端

使用BioClient即可

2.服务端,建立NioServer类
package me.muphy.io.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

public class NioServer {
//准备两个东西 轮询器(叫号系统)+缓冲区(等候区)
private Selector selector;
private ByteBuffer buffer = ByteBuffer.allocate(1024);
private int port = 8080;

public NioServer(int port) {
try {
this.port = port;
ServerSocketChannel socketChannel = ServerSocketChannel.open();
socketChannel.bind(new InetSocketAddress(this.port));
//为了兼容BIO NIO默认使用阻塞
socketChannel.configureBlocking(false);

//叫号系统工作
selector = Selector.open();

//开门营业
socketChannel.register(selector, SelectionKey.OP_ACCEPT);

} catch (IOException e) {
e.printStackTrace();
}
}

public void listen() {
System.out.println("listen on " + this.port + ".");
try {
while (true) {
selector.select();
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
process(key);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}

private void process(SelectionKey key) throws IOException {
if (key.isAcceptable()) {
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
SocketChannel channel = serverSocketChannel.accept();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel channel = (SocketChannel) key.channel();
int len = channel.read(buffer);
if (len > 0) {
buffer.flip();
String content = new String(buffer.array(), 0, len);
channel.register(selector, SelectionKey.OP_WRITE);
//在KEY上携带一个附件,一会儿写出去
key.attach(content);
System.out.println("读取内容:" + content);
}
} else if (key.isWritable()) {
SocketChannel channel = (SocketChannel) key.channel();
String attachment = (String) key.attachment();
channel.write(ByteBuffer.wrap(("输出:" + attachment).getBytes()));
channel.close();
}
}

public static void main(String[] args) {
new NioServer(8080).listen();
}
}

三、异步非阻塞AIO(AIO)

1.
服务端,建立AioServer类
package me.muphy.io.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AioServer {
private final int port;

public AioServer(int port) {
this.port = port;
}

public static void main(String[] args) throws IOException {
new AioServer(8080).listen();
}

private void listen() throws IOException {
ExecutorService executorService = Executors.newCachedThreadPool();
AsynchronousChannelGroup channelGroup = AsynchronousChannelGroup.withCachedThreadPool(executorService, 1);
final AsynchronousServerSocketChannel socketChannel = AsynchronousServerSocketChannel.open();
socketChannel.bind(new InetSocketAddress(this.port));
System.out.println("服务器已启动,监听端口:" + this.port);
socketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
final ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
@Override
public void completed(AsynchronousSocketChannel result, Object attachment) {
System.out.println("IO操作成功,开始获取数据");
try {
buffer.clear();
result.read(buffer).get();
buffer.flip();
result.write(buffer);
buffer.flip();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
try {
result.close();
socketChannel.accept(null, this);
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("操作完成");
}

@Override
public void failed(Throwable exc, Object attachment) {
System.out.println("IO操作失败:" + exc);
}
});

try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.客户端,建立AioClient类
package me.muphy.io.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;

public class AioClient {
private final AsynchronousSocketChannel client;

public AioClient() throws IOException {
this.client = AsynchronousSocketChannel.open();
}

public static void main(String[] args) throws IOException {
new AioClient().connent("localhost", 8080);
}

public void connent(String host, int port) {
client.connect(new InetSocketAddress(host, port), null, new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
try {
client.write(ByteBuffer.wrap("这是一条测试数据".getBytes())).get();
System.out.println("已发送至服务器");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}

@Override
public void failed(Throwable exc, Void attachment) {
exc.printStackTrace();
}
});
final ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer, null, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
System.out.println("IO操作完成:" + result);
System.out.println("获取反馈结果:" + new String(buffer.array()));
}

@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});

try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
 
四、Netty框架(NIO)

1.
服务端,建立NettyServer
package me.muphy.io.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

public class NettyServer {

private int port;

public NettyServer(int port) {
this.port = port;
}

public static void main(String[] args) throws InterruptedException {
new NettyServer(8080).start();
}

private void start() throws InterruptedException {

EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();

ServerBootstrap bootstrap = new ServerBootstrap();

bootstrap.group(bossGroup, workGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
// 这里面写逻辑
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
// new HttpResponseDecoder() 自定义编解码器
// pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4));
// pipeline.addLast(new LengthFieldPrepender(4));
pipeline.addLast("encoder", new ObjectEncoder());
pipeline.addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)));

pipeline.addLast(new ServerChannelHandler());
}
}).option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);

//正式启动服务器
ChannelFuture future = bootstrap.bind(this.port).sync();
System.out.println("服务器启动,监听端口:" + this.port);
future.channel().closeFuture().sync();
}

//业务处理
private class ServerChannelHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
String res = "服务端收到消息:" + msg;
System.out.println(res);
ctx.write("服务端回复消息:" + msg);
ctx.flush();
ctx.close();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("与客户端交互发生异常:" + ctx.name());
}
}
}

2.客户端,建立NettyClient
package me.muphy.io.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

public class NettyClient {

public static void main(String[] args) throws InterruptedException {
new NettyClient().connect();
}

public void connect() throws InterruptedException {
NioEventLoopGroup eventExecutors = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventExecutors)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
// new HttpResponseDecoder() 自定义编解码器
// pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4));
// pipeline.addLast(new LengthFieldPrepender(4));
pipeline.addLast("encoder", new ObjectEncoder());
pipeline.addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)));

pipeline.addLast(new ClientChannelHandler());
}
});
//正式链接
ChannelFuture future = bootstrap.connect("localhost", 8080).sync();
future.channel().writeAndFlush("测试数据").sync();
future.channel().closeFuture().sync();

}

private class ClientChannelHandler extends ChannelInboundHandlerAdapter{

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(msg);
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("连接服务器发生异常");
}
}

}
 
 
posted @ 2020-02-15 15:48  明月心~  阅读(297)  评论(0编辑  收藏  举报