2017-10-16 8 views
0

Curl 게시물을 Netchocket 소켓 서버에 만들어 주지만, FullHttpRequest로 객체 메시지를 캐스팅하려고하면 내 ChannelRead에 예외가 발생합니다. 나는 또한 내가 유효한 패킷을 얻거나하고 있지 않다 경우 확인하기 위해 와이어 샤크를 사용Netty- ChannelRead가 객체 메시지가 SimpleLeakAwareByteBuf 유형이라고보고합니다.

public class NettyHostSocketServer implements IClientSocketServer { 
    protected static boolean isClientHandlerRunning = false; 
    private static final Logger log = LoggerFactory.getLogger(SocketManager.class); 
    private static final int CLIENT_DATA_PORT = 9877; 
    private static final int MAX_CLIENTS = 5; 
    private HostPacketHandler hostPacketHandler; 

    public NettyHostSocketServer(RequestParser request) { 
     hostPacketHandler = new HostPacketHandler(request); 
    } 

    private boolean startSocket(int port) { 
     NioEventLoopGroup group = new NioEventLoopGroup(); 
     try { 
      ServerBootstrap b = new ServerBootstrap(); 
      b.group(group) 
        .channel(NioServerSocketChannel.class) 
        .localAddress(new InetSocketAddress(port)) 
        .childHandler(new ChannelInitializer<SocketChannel>() { 
         @Override 
         public void initChannel(SocketChannel ch) 
           throws Exception { 
          ch.pipeline().addLast(
            hostPacketHandler); 
         } 
        }); 

      ChannelFuture f = b.bind().sync(); 
      log.info("Started host-side socket server at Port {}",CLIENT_DATA_PORT); 
      return true; 
      // Need to do socket closing handling. close all the remaining open sockets 
      //System.out.println(EchoServer.class.getName() + " started and listen on " + f.channel().localAddress()); 
      //f.channel().closeFuture().sync(); 
     } catch (InterruptedException e) { 
      log.error("Error starting host-side socket"); 
      e.printStackTrace(); 
      return false; 
     } finally { 
      //group.shutdownGracefully().sync(); 
     } 
    } 

    @Override 
    public boolean start() { 

     if (!isClientHandlerRunning) { 
      isClientHandlerRunning = true; 
      return startSocket(CLIENT_DATA_PORT); 
     } 
     return true; 
    } 


    @Override 
    public int getActiveConnections() { 
     return 0; 
    } 
} 

: 다음

java.lang.ClassCastException: io.netty.buffer.SimpleLeakAwareByteBuf cannot be cast to io.netty.handler.codec.http.FullHttpRequest 
     at edu.clemson.openflow.sos.host.netty.HostPacketHandler.channelRead(HostPacketHandler.java:42) 
     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) 
     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:334) 
     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:326) 
     at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1320) 
     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) 
     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:334) 
     at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:905) 
     at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:123) 
     at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:563) 
     at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:504) 
     at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:418) 
     at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:390) 
     at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:742) 
     at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:145) 
     at java.lang.Thread.run(Thread.java:748) 

내 소켓 핸들러 클래스

@ChannelHandler.Sharable 
public class HostPacketHandler extends ChannelInboundHandlerAdapter { 
    private static final Logger log = LoggerFactory.getLogger(HostPacketHandler.class); 
    private RequestParser request; 

    public HostPacketHandler(RequestParser request) { 
     this.request = request; 
     log.info("Expecting Host at IP {} Port {}", 
       request.getClientIP(), request.getClientPort()); 
    } 

    public void setRequestObject(RequestParser requestObject) { 
     this.request = requestObject; 
    } 

    @Override 
    public void channelRead(ChannelHandlerContext ctx, Object msg) { 
     // Discard the received data silently. 
     InetSocketAddress socketAddress = (InetSocketAddress) ctx.channel().remoteAddress(); 
     log.info("Got Message from {} at Port {}", 
       socketAddress.getHostName(), 
       socketAddress.getPort()); 
     //FullHttpRequest request = (FullHttpRequest) msg; 
     log.info(msg.getClass().getSimpleName()); 
     //((ByteBuf) msg).release(); 
    } 

    @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
     // Close the connection when an exception is raised. 
     cause.printStackTrace(); 
     ctx.close(); 
    } 

} 

파이프 라인이다. 아래 Wireshark 덤프의 스크린 샷입니다. enter image description here

+1

파이프 라인에 HTTP 코덱이 있습니까? 그 코드를 보여줄 수 있습니까? – Nicholas

답변

0

귀하의 문제는 당신이 오류가 발생하는 이유는 실제 HttpRequest 객체로 ByteBuf를 디코딩 적이 있다는 것입니다. ByteBufFullHttpRequest 개체로 전송할 수 없습니다.

당신은 같이해야합니다 :

@Override 
public void initChannel(Channel channel) throws Exception { 
    channel.pipeline().addLast(new HttpRequestDecoder()) // Decodes the ByteBuf into a HttpMessage and HttpContent (1) 
     .addLast(new HttpObjectAggregator(1048576)) // Aggregates the HttpMessage with its following HttpContent into a FullHttpRequest 
     .addLast(hostPacketHandler); 
} 

(1) 당신은 또한 HttpRequestDecoder 및 HttpResponseEncoder을 추가이 핸들러 HttpServerCodec를 사용 HttpResponse에 보내려면.