【问题标题】:Client channel is not in writable state(NIO) Netty客户端通道不处于可写状态(NIO)Netty
【发布时间】:2013-02-22 04:17:06
【问题描述】:

客户端通道在 netty 中不处于可写状态。哪位高手能指导我找出原因

为什么通道总是不可写?

由于它不是可写状态,我们的线程处于睡眠模式。我们使用线程转储分析线程的状态,在下面的循环中添加了一个计数器,它等待一分钟然后退出循环。但我真的很想弄清楚不可写状态的原因。

频道关闭后是否还在ctx中(如果EOF不是客户端发送的)?

如果这会发生(意味着永远不会处于可写状态)?

while (!ctx.getChannel().isWritable()) {
    Thread.sleep(100);
    }

请帮忙。

非常感谢

【问题讨论】:

    标签: tcp client netty nio channel


    【解决方案1】:

    从表面上看,这是因为 ChannelBuffer 已满,即没有更多可写字节。

    这可能是由于写入速度太快,或者通道无法发送任何字节造成的。如果你没有写得太快,可能是因为通道没有成功发送写入的字节。

    【讨论】:

    • 我们向其他客户端的频道写入太快,无法通知其他客户端的断开连接。如果我们试图检查一个已经关闭的可写通道,但服务器没有检测到通道关闭事件,会发生这种情况吗???
    • @JohnChristy 我没有用netty,但希望你有办法测试一下通道是否关闭。
    • 是的,你是对的。但是如果我们没有得到通道关闭事件(由于网络故障)我们无法检查它是否关闭。如果我们在客户端和服务器之间有适当的网络,我们可以检查该特定通道是否已关闭。
    • @JohnChristy 在网络故障的情况下,检测另一端死机的正常程序是超时。如果该通道在一定时间内不可写,则可以认为该通道已关闭。如果你可以控制另一端,你也可以做你自己的保持活动心跳戳。如果在一定时间内没有收到另一端的心跳,则认为另一端已死,通道不可用。
    【解决方案2】:

    你应该使用选择器,或者 Netty 给你的任何东西,告诉你什么时候通道是可写的。你当然不应该通过循环睡觉来浪费时间。执行此操作时,通道状态无法更改。仅由select().更改

    【讨论】:

    • while (ctx.getChannel().isWritable()) { // write something } 如果我们这样写,它将等待选择器切换通道以写入 m 模式。如果通道处于其他状态并且无法以可写方式返回,则线程可能会进入无限循环。
    • @JohnChristy 没错,所以不要那样做。当你睡觉时,通道状态不会神奇地改变。您需要致电 select() 来完成此操作。
    猜你喜欢
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    相关资源
    最近更新 更多