0

我正在尝试关闭我的 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();
    }

}
4

2 回答 2

0

这是一个已知问题。一种解决方法是在再次绑定之前等待大约 5 秒。

于 2014-01-19T09:45:36.543 回答
0

组意味着线程。shutdowngracefully() 是释放线程资源,而不是关闭套接字。因此,您需要显式关闭套接字才能重新使用端口,如下所示。

future.Channel().close()

这意味着您需要将创建的服务器通道存储在代码中以用于关闭目的。

于 2013-10-28T03:50:15.820 回答