我正在尝试关闭我的 UDT 服务器(Netty 4.0.5.Final)shutDownGracefully()
并在同一端口上重新打开它。不幸的是,我总是得到下面的套接字异常,尽管它要等到未来完成。我还添加了套接字选项SO_REUSEADDR
。
这样做的正确方法是什么?
Exception in thread "main" com.barchart.udt.ExceptionUDT: UDT Error : 5011 : another socket is already listening on the same UDP port : listen0:listen [id: 0x323d3939]
at com.barchart.udt.SocketUDT.listen0(Native Method)
at com.barchart.udt.SocketUDT.listen(SocketUDT.java:1136)
at com.barchart.udt.net.NetServerSocketUDT.bind(NetServerSocketUDT.java:66)
at io.netty.channel.udt.nio.NioUdtAcceptorChannel.doBind(NioUdtAcceptorChannel.java:71)
at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:471)
at io.netty.channel.DefaultChannelPipeline$HeadHandler.bind(DefaultChannelPipeline.java:1006)
at io.netty.channel.DefaultChannelHandlerContext.invokeBind(DefaultChannelHandlerContext.java:504)
at io.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:487)
at io.netty.channel.ChannelDuplexHandler.bind(ChannelDuplexHandler.java:38)
at io.netty.handler.logging.LoggingHandler.bind(LoggingHandler.java:254)
at io.netty.channel.DefaultChannelHandlerContext.invokeBind(DefaultChannelHandlerContext.java:504)
at io.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:487)
at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:848)
at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:193)
at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:321)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:366)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:724)
一个小测试程序演示了这个问题:
public class MsgEchoServer {
public static class MsgEchoServerHandler extends ChannelInboundHandlerAdapter {
}
public void run() throws Exception {
final ThreadFactory acceptFactory = new UtilThreadFactory("accept");
final ThreadFactory connectFactory = new UtilThreadFactory("connect");
final NioEventLoopGroup acceptGroup = new NioEventLoopGroup(1,
acceptFactory, NioUdtProvider.MESSAGE_PROVIDER);
final NioEventLoopGroup connectGroup = new NioEventLoopGroup(1,
connectFactory, NioUdtProvider.MESSAGE_PROVIDER);
try {
final ServerBootstrap boot = new ServerBootstrap();
boot.group(acceptGroup, connectGroup)
.channelFactory(NioUdtProvider.MESSAGE_ACCEPTOR)
.option(ChannelOption.SO_BACKLOG, 10)
.option(ChannelOption.SO_REUSEADDR, true)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<UdtChannel>() {
@Override
public void initChannel(final UdtChannel ch) throws Exception {
ch.pipeline().addLast(new MsgEchoServerHandler());
}
});
final ChannelFuture future = boot.bind(1234).sync();
} finally {
acceptGroup.shutdownGracefully().syncUninterruptibly();
connectGroup.shutdownGracefully().syncUninterruptibly();
}
new MsgEchoServer().run();
}
public static void main(final String[] args) throws Exception {
new MsgEchoServer().run();
}
}