szhnet / kcp-netty

Java implementation of KCP based on Netty. 基于netty实现的java版kcp。
MIT License
329 stars 110 forks source link

为什么当服务器端close的时候,客户端不会调用channelInactive方法? #1

Closed benjaminpan8 closed 6 years ago

benjaminpan8 commented 6 years ago

当服务器端调用ctx.close()时,客户端不知道服务器close了,判断不了。

反之客户端调用ctx.close()的时候,服务器却能够调用channelInactive方法。

客户端代码 public class EchoClientHandler extends ChannelInboundHandlerAdapter {

@Override
public void channelActive(ChannelHandlerContext ctx) {
    UkcpChannel kcpCh = (UkcpChannel) ctx.channel();
    kcpCh.conv(EchoClient.CONV); // set conv

    //ctx.writeAndFlush(firstMessage);

    ByteBuf heapBuffer = Unpooled.buffer(18);  
    heapBuffer.writeBytes("测试我是客户端".getBytes()); 

    ctx.writeAndFlush(heapBuffer);
}

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {

    ctx.close();
}

@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
    ctx.flush();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    // Close the connection when an exception is raised.
    System.out.println("客户端调用 exceptionCaught!!!!!!!---------");
    cause.printStackTrace();
    ctx.close();
}

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    // TODO Auto-generated method stub
     System.out.println("客户端调用: channelInactive!!!!!!!");
    super.channelInactive(ctx);

}

}

服务器代码 public class EchoServerHandler extends ChannelInboundHandlerAdapter {

private final ByteBuf firstMessage;

/**
 * Creates a client-side handler.
 * @throws InterruptedException 
 */
public EchoServerHandler () throws InterruptedException {
    firstMessage = Unpooled.buffer(EchoClient.SIZE);
    for (int i = 0; i < firstMessage.capacity(); i++) {
        firstMessage.writeByte((byte) i);
    }
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    UkcpChannel kcpCh = (UkcpChannel) ctx.channel();
    kcpCh.conv(EchoServer.CONV);

}
int i = 0;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception{
        ctx.close();
}

@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
    ctx.flush();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    // Close the connection when an exception is raised.
    System.out.println("服务器调用exceptionCaught!!!!!!!111111111111111111111");
    cause.printStackTrace();
    ctx.close();
}

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    // TODO Auto-generated method stub
     System.out.println("服务器调用channelInactive!!!!!!!");
    super.channelInactive(ctx);

}

}

szhnet commented 6 years ago

KCP本身是一个ARQ协议,并没有涉及像TCP那样的连接状态管理问题。kcp-netty也没有额外做这部分。所以客户端并不知道服务器端进行了close。 当然你可以参考这里,用TCP连接辅助实现KCP连接的管理。或者在KCP协议的基础之上自己扩展实现。