2016-03-25 31 views
0

Netty'i yakın zamanda öğrenmeye başladım, ama bugün bir sorunum var. bu benim sunucu koduNetty server, müşteri isteğini ikinci kez karşılayamıyor

public class NettyServer2 { 

public static void main(String[] args) { 
    System.out.println("Server start"); 
    new NettyServer2().start(); 
} 

public void start() { 
    EventLoopGroup bossGroup = new NioEventLoopGroup(); 
    EventLoopGroup workerGroup = new NioEventLoopGroup(); 
    ServerBootstrap b = new ServerBootstrap(); 
    ChannelInitializer<SocketChannel> channelInit = new ChannelInitializer<SocketChannel>() { 
     @Override 
     protected void initChannel(SocketChannel ch) throws Exception { 
      ch.pipeline().addLast(new SeverHandler()); 
     } 

    }; 
    b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(channelInit) 
      .option(ChannelOption.SO_BACKLOG, 1024).childOption(ChannelOption.SO_KEEPALIVE, true); 
    try { 
     ChannelFuture f = b.bind(8000).sync(); 
     System.out.println("server started on port:8000"); 
     f.channel().closeFuture().sync(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      bossGroup.shutdownGracefully().sync(); 
      workerGroup.shutdownGracefully().sync(); 
     } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 
    } 
} 

}

sınıf SeverHandler SimpleChannelInboundHandler {

@Override 
protected void messageReceived(ChannelHandlerContext ctx, ByteBuf in) throws Exception { 
    System.out.println("server recevie:" + in.toString(CharsetUtil.UTF_8)); 
    ctx.writeAndFlush(in); 
} 

@Override 
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 
    Channel ch = ctx.channel(); 
    if (ch.isActive()) { 
     ch.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); 
    } 
} 

}

uzanır ve müvekkilim kodu vardır

public class NettyClient2 { 

private final String host; 
private final int port; 

public NettyClient2(String host, int port) { 
    this.host = host; 
    this.port = port; 
} 

public void start() throws InterruptedException { 
    EventLoopGroup group = new NioEventLoopGroup(); 
    Bootstrap b = new Bootstrap(); 
    ChannelInitializer<SocketChannel> channel = new ChannelInitializer<SocketChannel>() { 

     @Override 
     protected void initChannel(SocketChannel channel) throws Exception { 
      channel.pipeline().addFirst(new ClientHandler()); 
     } 

    }; 
    b.group(group).channel(NioSocketChannel.class).remoteAddress(new InetSocketAddress(host, port)) 
      .handler(new ClientHandler()); 

    try { 
     ChannelFuture f = b.connect().sync(); 
     f.channel().closeFuture().sync(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    }finally{ 
     group.shutdownGracefully().sync(); 
    } 
} 

public static void main(String[] args) throws InterruptedException { 
    new NettyClient2("127.0.0.1", 8000).start(); 
} 

}

sınıf ClientHandler'ın SimpleChannelInboundHandler {

private BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); 

@Override 
public void channelActive(ChannelHandlerContext ctx) throws Exception { 
    System.out.println("已经与Server建立连接..."); 
    System.out.println("\n请输入要发送的信息:"); 
    String in = sin.readLine(); 
    ctx.writeAndFlush(Unpooled.copiedBuffer(in,CharsetUtil.UTF_8)); 
} 

@Override 
protected void messageReceived(ChannelHandlerContext ctx, ByteBuf in) throws Exception { 
    System.out.println("client recevie:" + in.toString(CharsetUtil.UTF_8)); 
    System.out.println("已经与Server建立连接..."); 
    System.out.println("\n请输入要发送的信息:"); 
    String read = sin.readLine(); 
    ctx.writeAndFlush(Unpooled.copiedBuffer(read,CharsetUtil.UTF_8)); 
} 

} uzanır

istemci istemci konsolda ben girişi başlatılmıştır ve sunucunun isteği alacak

ama için istekte Sunucu ikinci kez istek alamıyor bir hata alıyorum. enter image description here

+0

sunucuda istisna bulmak sunucusunda kullandığım çünkü 1 –

+0

Tamam öyle düşünüyorum '(in) ctx.writeAndFlush;' –

+0

korumalı boşluğu messageReceived (ChannelHandlerContext ctx, ByteBuf in) özel durumunu atar { \t \t String inStr = in.toString (CharsetUtil.UTF_8); \t \t System.out.println ("server recevie:" + inStr); \t \t StringBuffer sb = new StringBuffer (inStr); \t \t inStr = sb.reverse(). ToString(); \t \t System.out.println ("reverse string:" + inStr); \t \t \t ccx.writeAndFlush (Unpooled.copiedBuffer (inStr, CharsetUtil.UTF_8)); –

cevap

0

Senin sorunun SimpleChannelInboundHandler sizin için otomatik tampon serbest bırakır gerçeği kaynaklanır.

Buna karşı koymak için, gönderim sırasında arabelleğe retain() numaralı telefonu aramalısınız. io.netty.util.IllegalReferenceCountException: refCnt: ​​0, eksiltme:

@Override 
protected void messageReceived(ChannelHandlerContext ctx, ByteBuf in) throws Exception { 
    System.out.println("server recevie:" + in.toString(CharsetUtil.UTF_8)); 
    ctx.writeAndFlush(in.retain()); 
} 
+0

Evet, öyle düşünüyorum.Ama neden? Bu konuda herhangi bir belge var mı? Ben googled ama çoğunlukla makaleler baz sürüm 4.xI kullanımı 5.0_alpaha –

+0

SimpleChannelInboundHandler arabelleği arabellemeyi neden arabellek serbest bırakması gerektiği anlamına gelir. –

+0

'SimpleChannelInboundHandler', kodun basitleştirilmesi için oluşturulmuş bir işleyici olduğundan, arabelleğin tam kod üzerinde bir son sonuç bloğu gerektirdiği için arabelleği serbest bırakır. Kanal 'InboundHandlerAdaptor da var' 'bunu yapmaz – Ferrybig