Java 净5%的代理问题
我在使用代理时遇到了一些问题。我正在使用netty lib netty-all-5.0.0.Alpha1.jar 在类的Java 净5%的代理问题,java,proxy,netty,Java,Proxy,Netty,我在使用代理时遇到了一些问题。我正在使用netty lib netty-all-5.0.0.Alpha1.jar 在类的initChannel方法中,我有 @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline cp = ch.pipeline(); cp.addLast(new LoggingHandler(LogLevel.IN
initChannel
方法中,我有
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline cp = ch.pipeline();
cp.addLast(new LoggingHandler(LogLevel.INFO));
cp.addLast("decoder", new StringDecoder());
cp.addLast("encoder", new StringEncoder());
cp.addLast(new HexDumpProxyFrontendHandler(remoteHost, remotePort));
}
在hextumpproxyfrontendhandler
类中,我想按如下方式处理传入消息,
在这里,我正在将Object msg
转换为String
,希望更改值,并且在发送修改后的字符串时遇到问题
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
String s1 = ((ByteBuf) msg).toString(Charset.defaultCharset());
if (outboundChannel.isActive()) {
outboundChannel.writeAndFlush(s1).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (future.isSuccess()) {
// was able to flush out data, start to read the next
// chunk
ctx.channel().read();
} else {
future.channel().close();
}
}
});
}
}
如果我发送的对象本身没有任何修改,其工作正常。但是如果我想发送字符串
,它不会引发任何异常,也不会工作
在启用initChannel
方法中的String
编码器和解码器之后,我得到以下错误:
Proxying *:9999 to 192.168.1.27:8554 ...
java.lang.ClassCastException: java.lang.String cannot be cast to io.netty.buffer.ByteBuf
at ivz.proxy.HexDumpProxyFrontendHandler.channelRead(HexDumpProxyFrontendHandler.java:68)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:74)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:138)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:320)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.ChannelHandlerInvokerUtil.invokeChannelReadNow(ChannelHandlerInvokerUtil.java:74)
at io.netty.channel.DefaultChannelHandlerInvoker.invokeChannelRead(DefaultChannelHandlerInvoker.java:138)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:320)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:127)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:485)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:452)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:346)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:794)
at java.lang.Thread.run(Unknown Source)
除了上面提到的方法,我没有改变代码中的任何内容。所以,我的问题是,我想在发送到服务器之前更改
Object msg
中的一些值,我如何才能做到这一点?或者换句话说,是否可以在writeAndFlush
方法中发送String
cp.addLast(new LoggingHandler(LogLevel.INFO));
cp.addLast("decoder", new StringDecoder());
cp.addLast("encoder", new StringEncoder());
cp.addLast(new HexDumpProxyFrontendHandler(remoteHost, remotePort));
StringDecoder
,所以在channelRead中接收的对象将始终是字符串
当您写回字符串对象时,StringEncoder会将其编码为ByteBuffctx.channel().read()
Netty将自动调用处理程序的channelRead()
方法channel().read()是必需的,如果您想限制/控制读取,要做到这一点,您在channel options中设置了auto read false,默认情况下auto read为true。已经很晚了,但我也很难做到这一点。
下面是我如何为我的案件解决的。
在HexDumpProxyFrontendHandler中,I类对channelActive()进行了以下更改:
因此,在此之后,在
channelRead
回调中(对于HexDumpProxyFrontendHandler和HexDumpProxyBackendHandler),消息将是String
感谢您的简短提示Jestan Nirojan。首先,在这里提问之前,我只是想把这个对象转换成字符串,看看我是否能写,然后我想修改字符串并发送它。1> 现在我已经清楚地了解了这个过程。我用它来测试Rtsp,使用Live555MS作为服务器,vlc作为客户端。如果我在pipeline conf中删除解码器/编码器,HDProxy可以正常工作,但正如我所提到的,我想更改请求中的一些值,所以我想使用解码器/编码器,但HDProxy没有在更改后抛出任何错误,正如您所说的,但它不工作。请帮我解决这个问题。2>我从netty5的例子中选取了这个项目。所以我以前不知道为什么要写这个ctx.channel().read().channel().read()是必需的,如果你想限制/控制读取,要做到这一点,你在通道选项中设置了auto read false,默认情况下auto read是true。如果你改变字符串s1=((ByteBuf)msg.toString(Charset.defaultCharset());到字符串s1=(字符串)msg;我想这会管用的。
@Override
public void channelActive(ChannelHandlerContext ctx) {
final Channel inboundChannel = ctx.channel();
// Start the connection attempt.
Bootstrap b = new Bootstrap();
b.group(inboundChannel.eventLoop()).channel(ctx.channel().getClass())
.handler(new HexDumpProxyBackendHandler(inboundChannel))
.option(ChannelOption.AUTO_READ, false);
ChannelFuture f = b.connect(remoteHost, remotePort);
outboundChannel = f.channel();
outboundChannel.pipeline().addFirst(new StringDecoder()); // this 2 lines
outboundChannel.pipeline().addFirst(new StringEncoder());
f.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
if (future.isSuccess()) {
// connection complete start to read first data
inboundChannel.read();
} else {
// Close the connection if the connection attempt has
// failed.
inboundChannel.close();
}
}
});
}