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 メソッドが終了するまでは、1 回のストロークではありません。残念ながら、私にはわかりません。ヒントをいただければ幸いです。

4

1 に答える 1

0

channelBoundNetty のすべてのコードを実行して Netty の I/O スレッドを保持しているため、できるだけ早く復帰する必要があります。

ExecutorNetty のスレッドの 1 つがコードの終了を待ってブロックされないように、実行時間の長いコード (この場合はdataReaderループ)を実行するために (または Netty ライブラリに同等のものがある場合は) を使用する必要があります。

于 2012-08-22T15:42:06.297 に答える