netty中ctx.writeAndFlush()没有将数据发送出去

问题描述:

因为某些极端网络环境,导致我传文件非常非常不方便,所以想到写了这么一个小工具,进行点对点的文件传输。现已放到github,https://github.com/chengpei/file-transfer
开发过程中遇到一个奇怪的问题,在我接收完了文件内容后,准备发送一个文件接收完成的指令,结果并没有发送出去,也就是下面倒数第26行

@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (!showProgressThread.isAlive()) {
            sending = true;
            startTime = System.currentTimeMillis();
            showProgressThread.start();
        }
        ByteBuf byteBuf = (ByteBuf) msg;
        int readableBytes = byteBuf.readableBytes();
        byte[] bytes = new byte[readableBytes];
        byteBuf.readBytes(bytes);
        fos.write(bytes);
        byteBuf.release();
        totalSize += readableBytes;
        count++;
        if (totalSize == prepareSendFileCommand.getFileSize()) {
            if (fos != null) {
                fos.close();
                sending = false;
                log.info("传输结束,耗时: {},平均速度:{}/s", getTimeStr(System.currentTimeMillis() - startTime), getNetFileSizeDescription(totalSize / (System.currentTimeMillis() - startTime) / 1000));
            }
            ctx.pipeline().remove(this);
            CompleteFileReceiveCommand completeFileReceiveCommand = new CompleteFileReceiveCommand();
            completeFileReceiveCommand.setPrepareSendFileCommand(prepareSendFileCommand);
            completeFileReceiveCommand.setElapsedTime(System.currentTimeMillis() - startTime);
            ctx.writeAndFlush(completeFileReceiveCommand);
            ConsoleManager.getInstance().finshRunningTask(prepareSendFileCommand.getTaskId());
        }
    }

原因分析:

这里发送的是一个Command对象,没有发送出去很可能是没有经过对应的编码器,当前这个handler是为了接收文件内容特地追加到pipeline链的最前端了,因为接收的文件不需要解码,直接写入文件即可,写完文件这个handler也会移除掉,方便接收后续指令解码。突然想到这里write是不是消息没有传递到pipeline的尾端,直接从当前的handler发回去了,这样就无法经过定义的CommandToByteEncoder编码器了,太久没用Netty了,一时没注意到这个细节。

解决方案:

使用pipeline的writeAndFlush方法就可以了,它的writeAndFlush可以直接从pipeline尾端发送,就可以经过所有的编码器了,替换为以下代码即可

ctx.pipeline().writeAndFlush(completeFileReceiveCommand);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值