import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollChannelOption;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import sun.misc.Signal;
import sun.misc.SignalHandler;
import java.net.InetSocketAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
public class ReusePortServer {
private final int port;
private List<Channel> bindingChannels = new LinkedList<>();
public ReusePortServer(int port) {
this.port = port;
}
private void initSignals() {
Signal.handle(new Signal("BUS"), new SignalHandler() {
@Override public void handle(Signal signal) {
System.out.println("signal arrived");
closeChannels();
}
});
}
synchronized private void closeChannels() {
for (Channel channel : bindingChannels) {
channel.close();
}
bindingChannels.clear();
}
synchronized private void registerChannel(Channel channel) {
bindingChannels.add(channel);
}
public void start() throws Exception {
initSignals();
EventLoopGroup group = new EpollEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(group)
.channel(EpollServerSocketChannel.class)
.option(EpollChannelOption.SO_REUSEPORT, true)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>(){
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ReusePortHandler());
registerChannel(ch);
}
});
for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
System.out.println(e.toString());
}
ChannelFuture f = b.bind().sync();
log(String.format("%s started and listen on %s", ReusePortServer.class.getName(), f.channel().localAddress()));
// registerChannel(ch); // ---------------I also tried to register this channel, but after my signaling, it closes my client's connection, rather than keeping it.
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
private final static SimpleDateFormat datefmt = new SimpleDateFormat("HH:mm:ss ");
public static void log(final String msg) {
System.out.print(datefmt.format(new Date()));
System.out.println(msg);
System.out.flush();
}
public static void main(final String[] args) throws Exception {
int port = 12355;
new ReusePortServer(port).start();
}
}
嗨,我正在寻找一种方法来阻止netty在服务器套接字上监听和接受,但是要完成当前连接上的任何正在进行的工作.
我遇到了以下问题:
How to stop netty from listening and accepting on server socket
根据它,我写了上面的代码,它接收信号(kill -7)来完成关闭.
但结果不是预期的,它会关闭tcp连接,而netty仍然可以接受新的连接.
我是否使用正确的停止网络方式来收听和接受?
这有什么不对?
最佳答案 您应该关闭ServerChannel,如下所示:
ChannelFuture f = b.bind().sync();
// Call this once you want to stop accepting new connections.
f.channel().close().sync();