Java原生阻塞IO
public classPlainOioServer {
public void serve(int port) throwsIOException {
final ServerSocket socket = newServerSocket(port);
try{
for(;;) {
final Socket clientSocket =socket.accept();
System.out.println(
"Accepted connection from " +clientSocket);
new Thread(newRunnable() {
@Override
public voidrun() {
OutputStream out;
try{
out =clientSocket.getOutputStream();
out.write("Hi!\r\n".getBytes(
Charset.forName("UTF-8")));
out.flush();
clientSocket.close();
} catch(IOException e) {
e.printStackTrace();
} finally{
try{
clientSocket.close();
} catch(IOException ex) {
// ignore on close
}
}
}
}).start();
}
} catch(IOException e) {
e.printStackTrace();
}
}
}
Java原生NIO
nio:选择并处理状态的变化
public classPlainNioServer {
public void serve(int port) throwsIOException {
ServerSocketChannel serverChannel =ServerSocketChannel.open();
serverChannel.configureBlocking(false);
ServerSocket ss =serverChannel.socket();
InetSocketAddress address = newInetSocketAddress(port);
ss.bind(address);
Selector selector =Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());
for(;;){
try{
selector.select();
} catch(IOException ex) {
ex.printStackTrace();
//handle exception
break;
}
Set readyKeys =selector.selectedKeys();
Iterator iterator =readyKeys.iterator();
while(iterator.hasNext()) {
SelectionKey key =iterator.next();
iterator.remove();
try{
if(key.isAcceptable()) {
ServerSocketChannel server =(ServerSocketChannel) key.channel();
SocketChannel client =server.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_WRITE |SelectionKey.OP_READ, msg.duplicate());
System.out.println(
"Accepted connection from " +client);
}
if(key.isWritable()) {
SocketChannel client =(SocketChannel) key.channel();
ByteBuffer buffer =(ByteBuffer) key.attachment();
while(buffer.hasRemaining()) {
if (client.write(buffer) == 0) {
break;
}
}
client.close();
}
} catch(IOException ex) {
key.cancel();
try{
key.channel().close();
} catch(IOException cex) {
// ignore on close
}
}
}
}
}
}
只有NIO和Epoll支持零拷贝
针对于Linux,自Linux内核版本 2.5.44后,引入epoll——一个高度可扩展的I/O事件通知特性,提供了比旧的POSIX select和poll系统调用更好的性能,Linux JDK NIO API使用了这些epoll调用
用法简单,只需要将NioEventLoopGroup替换为EpollEventGroup,并且把NioServerSocketChannel.class替换为EpollServerSocketChannel.class即可。
String os = System.getProperty("os.name");
if(os.toLowerCase().startsWith("win")){
System.out.println(os + " can't gunzip");
}
Netty实现阻塞IO
OIO的处理逻辑
public classNettyOioServer {
public void server(intport)
throwsException {
final ByteBuf buf =Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8")));
EventLoopGroup group = newOioEventLoopGroup();
try{
ServerBootstrap b = newServerBootstrap();
b.group(group)
.channel(OioServerSocketChannel.class)
.localAddress(newInetSocketAddress(port))
.childHandler(new ChannelInitializer() {
@Override
public voidinitChannel(SocketChannel ch)
throwsException {
ch.pipeline().addLast(
newChannelInboundHandlerAdapter() {
@Override
public voidchannelActive(
ChannelHandlerContext ctx)
throwsException {
ctx.writeAndFlush(buf.duplicate())
.addListener(
ChannelFutureListener.CLOSE);
}
});
}
});
ChannelFuture f =b.bind().sync();
f.channel().closeFuture().sync();
} finally{
group.shutdownGracefully().sync();
}
}
}
Netty实现NIO
public classNettyNioServer {
public void server(int port) throwsException {
final ByteBuf buf =Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Hi!\r\n",
Charset.forName("UTF-8")));
NioEventLoopGroup group = newNioEventLoopGroup();
try{
ServerBootstrap b = newServerBootstrap();
b.group(group).channel(NioServerSocketChannel.class)
.localAddress(newInetSocketAddress(port))
.childHandler(new ChannelInitializer() {
@Override
public voidinitChannel(SocketChannel ch)
throwsException {
ch.pipeline().addLast(
newChannelInboundHandlerAdapter() {
@Override
public voidchannelActive(
ChannelHandlerContext ctx) throwsException {
ctx.writeAndFlush(buf.duplicate())
.addListener(
ChannelFutureListener.CLOSE);
}
});
}
}
);
ChannelFuture f =b.bind().sync();
f.channel().closeFuture().sync();
} finally{
group.shutdownGracefully().sync();
}
}
}