java nio oio_Netty NIO transport && OIO transport

Netty NIO transport && OIO transport

9348a67d69a387c8e8d151f6c6da703e.png

OIO  transport

The  OIO  transport  is  a  compromise(妥协)  in  Netty.  It  builds  on  the  known  unified(统一)  API  but isn t asynchronous(异步) by nature because it uses the blocking java.net implementations under the hood.At  first  glance,this  transport  may  not  look  useful  to  you,  but  it  has  its  use  cases.

Because the OIO transport uses the java.net classes internally(内部的), it also uses the same logic that you may already be familiar with if you previously written network applications.When using these classes, you usually have one thread that handles the acceptance of newsockets (server-side) and then creates a new thread for each accepted connection to serve thetraffic  over  the  socket.  This  is  needed  asevery  I/O  operation  on  the  socket  may  block  at  anytime.If you share the same thread over more than one connection (socket),this could lead toa situation where blocking an operation could block all other sockets from doing their work.Knowing  that  operations  may  block,  you  may  start  to  wonder  how  Netty  uses  it  while  stillproviding  the  same  way  of  building  APIs.  Here Netty  makes  use  of  theSO_TIMEOUTthat  youcan set on a socket.This timeout specifies the maximum number of milliseconds to wait for anI/O operation  to  complete.If  the  operation  doesn t  complete  within  the  specified  timeout,  aSocketTimeoutException is  thrown.Netty  catches  this SocketTimeoutException andmoves on with its work. Then on the next EventLooprun, it tries again. Unfortunately, this isthe  only  way  to  do  this  and  still confirm the  inner  working  of  Netty.  The  problem  with  thisapproach(途径)  is  that  firing  the SocketTimeoutException isn t  free,  as  it  needs  to  fill  theStrackTrace, and so on.

90a155bed76a5c2750240c8798dd75da.png

Netty OIO 编程模型

package nio2;

import io.netty.bootstrap.ServerBootstrap;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.*;

import io.netty.channel.oio.OioEventLoopGroup;

import io.netty.channel.socket.SocketChannel;

import io.netty.channel.socket.oio.OioServerSocketChannel;

import java.net.InetSocketAddress;

import java.nio.charset.Charset;

/**

* Start  by  writing  a  blocking  version  of  the  application,

* but  this  time  use  Netty  as  a  network

* framework, as shown in the following listing.

* 这是netty的阻塞IO的写法,同时也是同步的

*/

public class NettyOioServer {

public void server(int port) throws Exception {

final ByteBuf buf = Unpooled.wrappedBuffer(

Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8")));

// Use OioEventLoopGroup Ito allow blocking mode (Old-IO)

EventLoopGroup group = new OioEventLoopGroup();

try {

ServerBootstrap b = new ServerBootstrap();

b.group(group)

.channel(OioServerSocketChannel.class)

.localAddress(new InetSocketAddress(port))

//Specify ChannelInitializer that will be called for each accepted connection

.childHandler(new ChannelInitializer() {

@Override

public void initChannel(SocketChannel ch) throws Exception {

ch.pipeline().addLast(

//Add ChannelHandler to intercept events and allow to react on them

new ChannelInboundHandlerAdapter() {

@Override

public void channelActive(ChannelHandlerContext ctx) throws Exception {

System.out.println("--active--");

//Write message to client and add ChannelFutureListener to close connection once message written

ctx.write(buf.duplicate()).addListener(ChannelFutureListener.CLOSE);

}

});

}

});

/**

* Bind server to accept connections

*/

ChannelFuture f = b.bind().sync();

f.channel().closeFuture().sync();

} finally {

group.shutdownGracefully().sync();

}

}

public static void main(String args[]) throws Exception {

int port = 9898;

NettyOioServer server = new NettyOioServer();

System.out.println("bind port " + port);

server.server(port);

}

}

NIO  transport

selector-based

The  NIO  transport  is  currently  the  most  used.  It  provides  a  full  asynchronous  implementation of all I/O operations by using the selector-based approach that s included in Java since Java 1.4 and the NIO subsystem.

The  idea  is  that  a  user  can  register  to  get  notified  once  a  channel s  state  changes.

Selection operation bit-set

OP_ACCEPT

Get notified once a new connection is accepted and a channel is created.

OP_CONNECT

Get notified once a connection attempt finishes.

OP_READ

Get notified once data is ready to be read out of the channel.

OP_WRITE

Get notified once it s possible to write more data to the channel. Most of the time this is possible, but it may not be because the OS socket buffer is completely filled. This usually happens when you write faster then the remote peer can handle it.

Netty s NIO transport uses this model internally to receive and send data, but exposes its own API to the user, which completely hides the internal implementation. As mentioned previously, that  helps  to  expose  only  one  unified(统一的)  API  to  the  user,  while  hiding  all  of  the  internals(内部).

8bcbb5b130f22225a0d911efab274d1d.png

One feature that offers only the NIO transport at the moment is called zero-file-copy . This feature allows you to quickly and efficiently transfer content from your file system.The feature provides a way to transfer the bytes from the file system to the network stack without copying the bytes from the kernel space(内核态) to the user space(用户态).

Netty NIO 异步非阻塞编程模型

package nio2;

import io.netty.bootstrap.ServerBootstrap;

import io.netty.buffer.ByteBuf;

import io.netty.buffer.Unpooled;

import io.netty.channel.*;

import io.netty.channel.nio.NioEventLoopGroup;

import io.netty.channel.socket.SocketChannel;

import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.InetSocketAddress;

import java.nio.charset.Charset;

/**

* Asynchronous networking with Netty

* For now, I'll note that you can use ChannelHandlerfor these tasks:

*  Transforming data from one format to another.

*  Notifying you of exceptions.

*  Notifying you when a Channel becomes active or inactive.

*  Notifying you once a channel is registered/deregistered from an EventLoop.

*  Notifying you about user-specific events.

*/

public class NettyNioServer {

public void server(int port) throws Exception {

final ByteBuf buf = Unpooled.wrappedBuffer(

Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8")));

EventLoopGroup group = new NioEventLoopGroup();

try {

ServerBootstrap b = new ServerBootstrap();

b.group(group)

.channel(NioServerSocketChannel.class)

.localAddress(new InetSocketAddress(port))

.childHandler(new ChannelInitializer() {

@Override

public void initChannel(SocketChannel ch) throws Exception {

ch.pipeline().addLast(

new ChannelInboundHandlerAdapter() {

@Override

public void channelActive(ChannelHandlerContext ctx) throws Exception {

System.out.println("--active--");

//Write message to client and add ChannelFutureListener to close connection once message written

ctx.write(buf.duplicate()).addListener(ChannelFutureListener.CLOSE);

}

});

}

});

/**

* Bind server to accept connections

*/

ChannelFuture f = b.bind().sync();

f.channel().closeFuture().sync();

} finally {

group.shutdownGracefully().sync();

}

}

public static void main(String args[]) throws Exception {

int port = 9898;

NettyOioServer server = new NettyOioServer();

System.out.println("bind port " + port);

server.server(port);

}

}

附:Netty提供的传输方式包括:

OIO

NIO

Local

Embedded

四种,以上只讲了两种。

写在后边

虽然通篇都是英文,但读起来感觉还是不错的,不常见的英文单词标注了中文。

通过最近一段时间的读英文文档,发现读起来不是很费劲了,至少感觉比读中文文档少了很多歧义。

自然有了google翻译的帮助,不会的单词都是小case,呵呵

=======END=======

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值