我正在尝试调整示例Netty代理,以便修改一些内容中的内容。
我在FTP客户端和服务器之间进行代理,因此行以CRLF结尾 - 这很重要。我还没有对FTP数据端口做任何事情,所以这不是一个因素。
我从这个示例代码开始:https://netty.io/4.0/xref/io/netty/example/proxy/package-summary.html
...设置这样的管道:
ch.pipeline().addLast(
new LoggingHandler(LogLevel.INFO),
new HexDumpProxyFrontendHandler(remoteHost, remotePort));
......这很好。
如果我添加new LineBasedFrameDecoder(maxLen)
,则ftp客户端挂起等待服务器,因为代理已经剥离了CRLF,服务器仍在等待。我可以通过告诉帧解码器不要删除分隔符来解决这个问题:new LineBasedFrameDecoder(maxLen, false, false)
。
ch.pipeline().addLast(
new LoggingHandler(LogLevel.INFO),
new LineBasedFrameDecoder(maxLen, false, false),
new HexDumpProxyFrontendHandler(remoteHost, remotePort));
到目前为止,这么好。但是如果我添加一个String解码器,我会得到相同的挂起症状,这次是因为没有调用StringDecoder之后的管道步骤。
ch.pipeline().addLast(
new LoggingHandler(LogLevel.INFO),
new LineBasedFrameDecoder(maxLen, false, false),
new StringDecoder(StandardCharsets.UTF_8),
// aim is for my own string rewriter to go here
new StringEncoder(StandardCharsets.UTF_8),
new HexDumpProxyFrontendHandler(remoteHost, remotePort));
在调试器中,StringEncoder.encode()中的断点不会触发。
如何判断Netty在解码后处理字符串?
答案 0 :(得分:1)
StringEncoder是一个出站通道适配器。它的目的是在写入时从String转换为ByteBuf,因此我不希望在入站数据上调用encode。
为了使代码正常工作,您需要将StringEncoder替换为入站通道适配器,该适配器在读取时从String转换为ByteBuf。我怀疑Netty库中是否存在任何此类编解码器,因为解码器通常从较低级别格式转换为较高级别格式,而不是相反。
由于LineBasedFrameDecoder发出ByteBuf并且HexDumpProxyFrontendHandler使用ByteBufs,我建议你删除StringDecoder和StringEncoder并插入你的客户重写器。但是..使它成为ByteBuf到ByteBuf解码器。在解码器中,您可以将传入的ByteBuf转换为String,完成您的工作,然后将其转换回ByteBuf,然后将其传递给管道。