Java 净5%的代理问题

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

我在使用代理时遇到了一些问题。我正在使用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.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));
  • 由于在HexDumpProxyFrontendHandler之前有
    StringDecoder
    ,所以在channelRead中接收的对象将始终是字符串

    当您写回字符串对象时,StringEncoder会将其编码为ByteBuff

  • 在ChannelFutureListener实现中,无需调用
    ctx.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();
                }
            }
        });
    }