当前位置: 首页 > 知识库问答 >
问题:

网是可写的()

裘安阳
2023-03-14

我正在为在线游戏运行Netty服务器,但是我遇到了一些奇怪的行为:

随机地,通道只是停止能够从服务器写入,即用户仍然连接,传入的数据被接收,但传出的数据没有到达客户端

我花了时间来调试这个问题,我发现channel.isWriteable()为连接有问题的客户端返回false。

有人能解释一下为什么会发生这种情况吗?

通道无法写入的原因是什么?

顺便说一句,这在本地主机连接上也会发生。

    public ChannelFuture write(Packet message) {
    ioWrite++;

    if (!channel.isConnected()) {
        System.err.println("Trying to write to bad channel");

        return null;
    }

    if (!channel.isWritable()) {
        System.err.println("Channel buffer is full?");
    }

    if ((channel != null) && channel.isConnected()) {
        return channel.write(message);
    }

    return null;
}

编码器:

public class GameProtocolEncoder extends OneToOneEncoder {



private ChannelBuffer response;


protected Object encode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {
    Packet p = (Packet) o;

    try {
        byte[] data       = p.getData();
        int    dataLength = p.getLength();

        if (p.getLength() > 5000) {
            System.err.println("unable to write data chunk to large");

            return null;
        }

        if (!p.isBare()) {
            int siz = 0;

            siz      += (p.getSize() == Packet.Size.VariableShort)
                        ? 2
                        : 1;
            siz      += (p.getId() > 128)
                        ? 2
                        : 1;
            response = ChannelBuffers.buffer(siz + p.getLength());

            int id          = p.getId();

            if (id< 128) {
                response.writeByte(id);
            } else {
                response.writeByte((byte) ((id >> 8) + 128));
                response.writeByte((byte) (id & 0xFF));
            }

            if (p.getSize() != Packet.Size.Fixed) {    // variable length
                if (p.getSize() == Packet.Size.VariableByte) {
                    if (dataLength > 255) {            // trying to send more data then we can represent with 8 bits!
                        throw new IllegalArgumentException("Tried to send packet length " + dataLength
                                                           + " in 8 bits [pid=" + p.getId() + "]");
                    }

                    response.writeByte((byte) dataLength);
                } else if (p.getSize() == Packet.Size.VariableShort) {
                    if (dataLength > 5000) {
                        throw new IllegalArgumentException("Tried to send packet length to big: " + id);
                    }

                    response.writeShort((short) dataLength);
                }
            }
        } else {
            response = ChannelBuffers.buffer(dataLength);
        }

        response.writeBytes(p.getData());

        return response;
    } catch (Exception e) {
        Logger.err("Error handling message: " + p);
        Logger.err(e);
    }

    return null;
}

共有2个答案

司马高明
2023-03-14

当它的套接字发送缓冲区填满时,通道停止可写,这反过来又发生在发送方超过接收方时。

如果它发生了很多,你可能想考虑加快你的接收代码,但一般来说,它可能随时发生,你所能做的就是推迟写入,直到通道再次变得可写。

慕容越泽
2023-03-14

我认为问题出在这里,你没有冲洗通道。试着用channel.writeAndFlush代替channel.write(…)。

 类似资料:
  • 我正在Android上创建一个定制的BLE服务,它只有一个可以读/写的特性。代码如下所示: 对add特征(...)的调用返回true。服务本身被创建,可以被广告,服务及其特性可以被客户发现。在客户端代码的其他地方,在定位所述服务的BLE扫描之后,运行的发现代码如下所示: 正如我所提到的,当这个服务发现代码运行时,它会发现定制服务和定义的特征。我为特征属性设置的任何值都会在客户端发现时正确显示。该特

  • 从 Netty api 中,它显示如果可写返回 false,请求将被排队。我能知道请求将在哪里排队吗?在什么情况下,队列可能已满并导致 OOM 问题? 以下是isWritable()的文档 当且仅当I/O线程将立即执行请求的写入操作时返回true。当此方法返回false时发出的任何写入请求都将排队,直到I/O线程准备好处理排队的写入请求。 https://netty.io/4.1/api/io/n

  • 我正在编写一个带有事务回滚的简单json数据库。我需要向一个文件追加一行文本,然后根据追加是否成功,将成功或失败记录到另一个文件。如果需要,第二个文件用于回滚。因此,在继续之前,我需要确定写操作是否成功。 我使用stream.write追加我的文本行,其中包括一个回调,应该验证写操作的成功或失败。 然后我在下面的URL上的NodeJS文档中读到了这个不幸的消息https://nodejs.org/

  • 我需要一个不可重入的读写锁,因为锁可能由获取它的线程以外的线程释放。(我意识到这一点时,我开始间歇性地获取非法监视器状态异常。) 我不确定不可重入是否是正确的术语。ReentrantLock允许当前持有锁的线程再次获取它。我不想要这种行为,因此我称之为“不可重入”。 上下文是我有一个使用线程池的套接字服务器。每个连接没有一个线程。请求可能由不同的线程处理。客户端连接可能需要在一个请求中锁定,在另一

  • 问题内容: 这是场景: ThreadA将要从某些套接字读取,并将数据写入“ MyFile.txt” ThreadB将读取“ MyFile”,到达末尾时,它将循环播放,直到MyFile中有新数据可用为止(因为我不想重新打开“ MyFile.txt”,并且浪费时间,所以我到达了从我所在的位置..)。 可以做这样的事情吗? 如果没有,还有其他方法可以做这种事情吗? 问题答案: 您提到的问题是著名的生产者

  • 想改进这个问题吗 通过编辑此帖子,添加详细信息并澄清问题。 这是我的if语句。我只想写得更短。因为我认为这些是无效的。顺便说一句,每个if语句都是独立的。