Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
319 views
in Technique[技术] by (71.8m points)

java - Netty doesn't write

When trying to write with netty, the written data never ends up at the remote side, confirmed with Wireshark.

I have tried:

//Directly using writeAndFlush
channel.writeAndFlush(new Packet());

//Manually flushing
channel.write(new Packet());
channel.flush();

// Even sending bytes won't work:
channel.writeAndFlush(new byte[]{1,2,3});

No exception is caught when I wrap it in try{...}catch(Throwable e){e.printStackTrace();}

What can I do to debug this problem?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Netty is asynchronous, meaning that it won't throw exceptions when a write failed. Instead of throwing exceptions, it returns a Future<?> that will be updated when the request is done. Make sure to log any exceptions coming from this as your first debugging steps:

channel.writeAndFlush(...).addListener(new GenericFutureListener<Future<Object>>() {
    @Override
    public void operationComplete(Future<Object> future) {
        // TODO: Use proper logger in production here
        if (future.isSuccess()) {
            System.out.println("Data written succesfully");
        } else {
            System.out.println("Data failed to write:");
            future.cause().printStackTrace();
        }
    }
});

Or more simply:

channel.writeAndFlush(...).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);

After you get the root cause of the exception, there could be multiple problems:

java.lang.UnsupportedOperationException:
unsupported message type: <type> (expected: ...)

Notice: This also throws when using an ObjectEncoder, but your object does not implements Serializable

A default Netty channel can only send ByteBufs and FileRegions. You need to convert your objects to these types either by adding more handlers to the pipeline, or converting them manually to ByteBufs.

A ByteBuf is the Netty variant of a byte array, but has the potential for performance because it can be stored in the direct memory space.

The following handlers are commonly used:

To convert a String use a StringEncoder To convert a Serializable use a ObjectEncoder (warning, not compatible with normal Java object streams) To convert a byte[] use a ByteArrayEncoder

Notice: Since TCP is a stream based protocol, you usually want some form of packet sizes attached, since you may not receive exact packets that you write. See Dealing with a Stream-based Transport in the Netty wiki for more information.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...