netty如何主动关闭连接

zhangyshun 2016-06-30 04:43:59
使用telnet连接服务端,发送退出指令,是可以断开连接的。但使用客户端连接,就关闭不了

服务端

public void bind() throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();

try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup);
bootstrap.channel(NioServerSocketChannel.class);
bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringDecoder(Charset.forName("utf-8")));
pipeline.addLast(new StringEncoder(Charset.forName("utf-8")));
pipeline.addLast(new NettyServerHandler());
}
});

bootstrap.bind("127.0.0.1", 5000).sync().channel().closeFuture().sync();

} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}


public class NettyServerHandler extends SimpleChannelInboundHandler<String> {

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.write("Welcome to" + InetAddress.getLocalHost().getHostName() + "!\r\n");
ctx.flush();
}

@Override
public void channelRead0(ChannelHandlerContext ctx, String request) throws Exception {
LogUtil.log("server channelRead0 : " + request);

String response = "server receive : " + request;
boolean close = false;
if (request.indexOf("bye") == 0) {
close = true;
response = "系统退出" + "\r\n";
}

ChannelFuture future = ctx.writeAndFlush(response);
if (close) {
// future.addListener(ChannelFutureListener.CLOSE).sync().channel().closeFuture().sync();
future.addListener(ChannelFutureListener.CLOSE);
}
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}


客户端
public void connect() throws InterruptedException {
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(workerGroup);
bootstrap.channel(NioSocketChannel.class);
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringDecoder(Charset.forName("utf-8")));
pipeline.addLast(new StringEncoder(Charset.forName("utf-8")));
pipeline.addLast(new NettyClientHandler());
}
});

bootstrap.connect("127.0.0.1", 5000).sync().channel().closeFuture().sync();

} finally {
}
}


public class NettyClientHandler extends SimpleChannelInboundHandler<String> {

@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg)
throws Exception {
LogUtil.log("client channelRead0 : " + msg);

if (msg.contains("系统退出")) {
LogUtil.log("client ctx.close()");
ctx.close();

} else {
ctx.writeAndFlush("aaa");
ctx.writeAndFlush("bye");
}
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}



使用telent就没有问题

...全文
10334 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
fishjam 2016-11-09
  • 打赏
  • 举报
回复
5.0都已经被废弃了,居然还想升级. 估计可能是粘包了, 可以加入 LineBasedFrameDecoder 试试. 而且可以看看服务器端日志里的 "server channelRead0 :" 打出来的具体值是什么.
zhangyshun 2016-07-01
  • 打赏
  • 举报
回复
把netty版本升到5.0就没问题了
qq_15915835 2016-06-30
  • 打赏
  • 举报
回复
直接在服务端调用ctx.close();

50,526

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧