Java netty DefaultChannelPipeline 异常捕获
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24979610/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
netty DefaultChannelPipeline exceptionCaught
提问by Thufir
Unfortunately, I don't understand this output from the netty server:
不幸的是,我不明白来自 netty 服务器的这个输出:
BUILD SUCCESSFUL
Total time: 3 seconds
Jul 27, 2014 2:04:44 AM io.netty.handler.logging.LoggingHandler channelRegistered
INFO: [id: 0xcad25a31] REGISTERED
Jul 27, 2014 2:04:44 AM io.netty.handler.logging.LoggingHandler bind
INFO: [id: 0xcad25a31] BIND(0.0.0.0/0.0.0.0:4454)
Jul 27, 2014 2:04:44 AM io.netty.handler.logging.LoggingHandler channelActive
INFO: [id: 0xcad25a31, /0:0:0:0:0:0:0:0:4454] ACTIVE
Jul 27, 2014 2:04:59 AM io.netty.handler.logging.LoggingHandler logMessage
INFO: [id: 0xcad25a31, /0:0:0:0:0:0:0:0:4454] RECEIVED: [id: 0xff40b8a2, /127.0.0.1:37558 => /127.0.0.1:4454]
Jul 27, 2014 2:04:59 AM net.bounceme.dur.netty.ServerHandler <init>
INFO: starting..
Jul 27, 2014 2:04:59 AM io.netty.channel.DefaultChannelPipeline$TailContext exceptionCaught
WARNING: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.handler.codec.TooLongFrameException: Adjusted frame length exceeds 1048576: 2901213193 - discarded
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.fail(LengthFieldBasedFrameDecoder.java:501)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.failIfNecessary(LengthFieldBasedFrameDecoder.java:477)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:403)
at io.netty.handler.codec.serialization.ObjectDecoder.decode(ObjectDecoder.java:68)
at io.netty.handler.codec.LengthFieldBasedFrameDecoder.decode(LengthFieldBasedFrameDecoder.java:343)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:241)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:149)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:125)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:116)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:744)
^Cthufir@dur:~/NetBeansProjects/AgentServer$
thufir@dur:~/NetBeansProjects/AgentServer$
Presumably the netty-based server is complaining that it's receiving bad data in some respect?
据推测,基于 netty 的服务器抱怨它在某些方面收到了错误的数据?
client code:
客户端代码:
package net.bounceme.dur.client.gui;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import net.bounceme.dur.client.jdbc.Title;
public final class ApplicationDriver {
private static final Logger log = Logger.getLogger(ApplicationDriver.class.getName());
private TitlesGUI gui = null;
private Handler handler = null;
public ApplicationDriver() throws IOException, ClassNotFoundException {
handler = new FileHandler("application.log");
handler.setFormatter(new SimpleFormatter());
log.setLevel(Level.INFO);
log.addHandler(handler);
log.info("starting log..");
MyProps p = new MyProps();
String host = p.getHost();
int port = p.getServerPort();
guiThread();
readWrite(host, port);
}
private void guiThread() {
Thread g;
g = new Thread() {
@Override
public void run() {
try {
gui = new TitlesGUI();
} catch (IOException ex) {
log.severe(ex.toString());
}
gui.setVisible(true);
}
};
g.start();
}
public static void main(String... args) throws IOException, ClassNotFoundException {
new ApplicationDriver();
}
private void readWrite(final String host, final int port) throws IOException {
Thread inputOutput;
final Socket socket = new Socket(host, port);
inputOutput = new Thread() {
@Override
public void run() {
while (true) {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream())) {
gui.setTitle((Title) objectInputStream.readObject());
Thread.sleep(1000);
} catch (IOException | ClassNotFoundException | InterruptedException ex) {
log.severe(ex.toString());
}
}
}
};
inputOutput.start();
}
}
is it a problem that the client is using regular sockets instead of netty? Both on the client and server side POJO's are being sent. (The Title
class is serializable and the serialVersionUID values match up.)
客户端使用常规套接字而不是 netty 是否有问题?正在发送客户端和服务器端的 POJO。(Title
该类是可序列化的并且 serialVersionUID 值匹配。)
a method from the GUI client (which is a bit large, it's a Netbeans Swing JFrame):
来自 GUI 客户端的一个方法(有点大,它是一个 Netbeans Swing JFrame):
public void setTitle(Title title) {
this.title = title;
text.setText(title.toString());
}
the point of the above method is for somethingto send objects to the GUI, which is then updated accordingly. Similarly, I want to fire updates, or other-wise wire the GUI to socket i/o.
上述方法的点是东西将对象发送到GUI中,然后相应地更新。同样,我想触发更新,或者以其他方式将 GUI 连接到套接字 i/o。
I don't really understand the output from the netty server. Is it a problem that the server uses netty while the client uses sockets? Both use the same POJO, with the serialVersionUID value. Here's the netty handler code:
我不太了解 netty 服务器的输出。服务器使用netty而客户端使用套接字是否有问题?两者都使用相同的 POJO,具有 serialVersionUID 值。这是 netty 处理程序代码:
package net.bounceme.dur.netty;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.util.logging.Logger;
import net.bounceme.dur.jdbc.Title;
public class ServerHandler extends SimpleChannelInboundHandler<Title> {
private static final Logger log = Logger.getLogger(ServerHandler.class.getName());
public ServerHandler() {
log.info("starting..");
}
@Override
public boolean acceptInboundMessage(Object msg) throws Exception {
log.info(msg.toString());
return true;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
log.info(msg.toString());
ctx.write(new Title());
}
@Override
protected void channelRead0(ChannelHandlerContext chc, Title title) throws Exception {
log.info(title.toString());
chc.write(new Title());
}
}
Apparently, none of the server handler code is executed, as everything explodes immediately after the client connects.
显然,没有执行任何服务器处理程序代码,因为在客户端连接后一切都会立即爆炸。
server code:
服务器代码:
package net.bounceme.dur.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.security.cert.CertificateException;
import java.util.logging.Logger;
import javax.net.ssl.SSLException;
public final class Server {
private static final Logger log = Logger.getLogger(Server.class.getName());
public static void main(String[] args) throws Exception {
MyProps p = new MyProps();
int port = p.getServerPort();
new Server().startServer(port, false);
}
private void startServer(int port, boolean ssl) throws CertificateException, SSLException, InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(
new ObjectEncoder(),
new ObjectDecoder(ClassResolvers.cacheDisabled(null)),
new ServerHandler());
}
});
b.bind(port).sync().channel().closeFuture().sync();
log.info("connected!");
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
采纳答案by trustin
The TooLongFrameException
raised by LengthFieldBasedFrameDecoder
means one of the following:
在TooLongFrameException
通过升高LengthFieldBasedFrameDecoder
装置执行下列操作之一:
- The remote peer sent a very large message, which exceeds the limit. The default maximum length of a message is 1 MiB. If you expect to receive a message larger than that, specify an alternative maximum length when you construct a
LengthFieldBasedFrameDecoder
. - You passed wrong parameters to
LengthFieldBasedFrameDecoder
so that it is decoding a wrong place in your message. In this case, you'd better re-read the Javadoc ofLengthFieldBasedFrameDecoder
to specify the correct values for you.
- 远程对等方发送了非常大的消息,超出了限制。消息的默认最大长度为 1 MiB。如果您希望收到大于该值的消息,请在构造
LengthFieldBasedFrameDecoder
. - 您传递了错误的参数,
LengthFieldBasedFrameDecoder
因此它在您的消息中解码了错误的位置。在这种情况下,您最好重新阅读的 JavadocLengthFieldBasedFrameDecoder
为您指定正确的值。