同步、异步,阻塞、非阻塞
Java IO
Netty
Netty的底层框架原理 入门理解
45 张图深度解析 Netty 架构与原理
JAVA中BIO、NIO、AIO的分析理解
netty 面试
你要的Netty常见面试题总结,敖丙搞来了!Netty使用模板
package openflow;
import openflow.init.OFProperties;
import openflow.protocol.connection.service.ServerFacade;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.InetSocketAddress;
public class TcpHandler implements ServerFacade {
private final Logger log = LoggerFactory.getLogger(getClass());
private int port;
private String address;
private final InetAddress startupAddress;
private EventLoopGroup workerGroup;
private EventLoopGroup bossGroup;
private final SettableFuture<Boolean> isOnlineFuture;
private Class<? extends ServerSocketChannel> socketChannelClass;
private TcpChannelInitializer channelInitializer;
private OFProperties properties;
public TcpHandler(OFProperties properties, int port) {
this(properties, null, port);
}
private TcpHandler(OFProperties properties, InetAddress startupAddress , int port) {
this.properties = properties;
this.startupAddress = startupAddress;
this.port = port;
isOnlineFuture = SettableFuture.create();
}
@Override
public void startServer() {
final ChannelFuture f;
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(socketChannelClass)
.handler(new LoggingHandler(LogLevel.DEBUG))
.childHandler(channelInitializer)
.option(ChannelOption.SO_BACKLOG, 128)
.option(ChannelOption.SO_REUSEADDR, true)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY , true)
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
// .childOption(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, getWriteHighWatermark() * 1024)
// .childOption(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, getWriteLowWatermark() * 1024)
.childOption(ChannelOption.WRITE_SPIN_COUNT, getWriteSpinCount());
// InetAddress address = InetAddress.getByName("192.168.6.11");
// f = b.bind(address,port).sync();
f = b.bind(port).sync();
} catch (InterruptedException e) {
log.error("Interrupted while binding port {}", port, e);
return;
}
try {
InetSocketAddress isa = (InetSocketAddress) f.channel().localAddress();
address = isa.getAddress().getHostAddress();
// Update port, as it may have been specified as 0
this.port = isa.getPort();
log.info("address from tcphandler: {}", address);
isOnlineFuture.set(true);
log.info("Switch listener started and ready to accept incoming tcp/tls connections on port: {}", port);
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
log.error("Interrupted while waiting for port {} shutdown", port, e);
} finally {
shutdownServer();
}
}
@Override
public void shutdownServer() {
// TODO Auto-generated method stub
}
// private int getWriteHighWatermark() {
// return 64;
return (int) Prop.get("",DEFAULT_WRITE_HIGH_WATERMARK);
// }
//
// private int getWriteLowWatermark() {
// return 32;
return (int) Prop.get("",DEFAULT_WRITE_LOW_WATERMARK);
// }
private int getWriteSpinCount() {
return 16;
}
public TcpChannelInitializer getChannelInitializer() {
return channelInitializer;
}
public void setChannelInitializer(TcpChannelInitializer channelInitializer) {
this.channelInitializer = channelInitializer;
}
@Override
public ListenableFuture<Boolean> getIsOnlineFuture() {
// TODO Auto-generated method stub
return null;
}
public void initiateEventLoopGroups(boolean isEpollEnabled) {
if(isEpollEnabled) {
initiateEpollEventLoopGroups();
} else {
initiateNioEventLoopGroups();
}
}
public void initiateNioEventLoopGroups() {
socketChannelClass = NioServerSocketChannel.class;
if(properties.getNettyBossGroup() != null && properties.getNettyWorkGroup() != null) {
bossGroup = new NioEventLoopGroup(properties.getNettyBossGroup());
workerGroup = new NioEventLoopGroup(properties.getNettyWorkGroup());
}else {
bossGroup = new NioEventLoopGroup();
workerGroup = new NioEventLoopGroup();
}
((NioEventLoopGroup)workerGroup).setIoRatio(100);
}
protected void initiateEpollEventLoopGroups() {
try {
socketChannelClass = EpollServerSocketChannel.class;
if(properties.getNettyBossGroup() != null && properties.getNettyWorkGroup() != null) {
bossGroup = new EpollEventLoopGroup(properties.getNettyBossGroup());
workerGroup = new EpollEventLoopGroup(properties.getNettyWorkGroup());
}else {
bossGroup = new EpollEventLoopGroup();
workerGroup = new EpollEventLoopGroup();
}
((EpollEventLoopGroup)workerGroup).setIoRatio(100);
return;
} catch (Throwable ex) {
log.debug("Epoll initiation failed");
}
//Fallback mechanism
initiateNioEventLoopGroups();
}
}