java - Netty 是可写的()

标签 java tcp netty

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

随机地, channel 停止从服务器写入,即用户仍然连接并且接收传入数据,但传出数据无法到达客户端。

我花时间对此进行了调试,我发现channel.isWriteable() 在连接客户端时返回 false 来解决问题。

任何人都可以解释为什么会发生这种情况吗?

channel 不再可写的原因是什么?

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

    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;
}

最佳答案

我认为问题出在你没有刷新 channel 。尝试用channel.writeAndFlush(...)替换channel.write(...)。

关于java - Netty 是可写的(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27952122/

相关文章:

javascript - 通过javascript代码获取带有Jsoup填充body标签的Html内容

java - 构造函数什么时候初始化?

java - 如何在 Tomcat 服务器上保存和加载图像

android - 无法通过 TCP/IP 连接 Android ADB

java - 当发送到服务器的消息数量较多时,Netty 中客户端收不到消息

http - 使用 Netty 管理服务器的 HTTP keep-alive 超时

java - 我不明白这个 return 语句的行为

java - DataOutput.writeByte()/DataInput.readByte() 或其他等效项在 Java 中如何工作?

python套接字不能发送多个消息——数据在赋值之前被引用——

java - Netty + JMeter,重用连接时出错