1

使用 Netty 3.5.3 我正在实现一个 UDP 服务器,它必须连续发送小数据包,而无需任何请求-响应通信。在论坛的任何地方,我发现最好的方法是重写 SimpleChannelHandler 的 channelBound 方法。

private static class MyHandler extends SimpleChannelHandler {

    private TargetDataReader dataReader = new TargetDataReader();

    private InetSocketAddress remoteAddress;

    private long sleep;

    /**
     * @param host
     * @param port
     */
    public MyHandler(String host, int port, long sleep) {
        super();
        this.remoteAddress = new InetSocketAddress(host, port);
        this.sleep = sleep;
    }

    /*
     * {@inheritDoc}
     */
    @Override
    public void channelBound(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        Channel ch = e.getChannel();

        int cnt = 0;
        long start = System.currentTimeMillis();

        byte[] targetData;
        while ((targetData = dataReader.nextData()) != null) {

            ChannelBuffer tdBuf = ChannelBuffers.wrappedBuffer(targetData);

            ++cnt;
            ChannelFuture cf = ch.write(tdBuf, this.remoteAddress);
            cf.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    System.out.println("Server - record sent "
                            + (future.isSuccess() ? "successfully" : "failed"));
                }
            });
            cf.await(30);

            if (sleep > 0)
                Thread.sleep(sleep);

            System.out.println("Server - written records " + cnt);
        }

        long duration = System.currentTimeMillis() - start;
        System.out.println("Server - duration=" + duration + ", cnt=" + cnt + ", records/sec="
                + String.format("%f", ((double) cnt) / duration * 1000));
    }

乍一看,它似乎有效。但深入研究后,我意识到接收客户端只收到了大约 50% 的数据包。此外,我认为这是实际的问题,调用ChannelFuture cf = ch.write(tdBuf, this.remoteAddress); 时服务器并没有真正发送数据包;但直到 channelBound 方法完成,而不是一击。不幸的是,我不知道,如果能得到提示,我将不胜感激。

4

1 回答 1

0

您需要尽快从那里返回,channelBound因为您通过在那里运行所有代码来阻止 Netty 的 I/O 线程。

您应该使用Executor(或 Netty 库中的等价物,如果存在)来执行长时间运行的代码(在本例中为dataReader循环),这样 Netty 的线程之一就不会阻塞等待您的代码完成。

于 2012-08-22T15:42:06.297 回答