繁体   English   中英

使InputStream成为非阻塞

[英]Make InputStream non-blocking

目前,我有一台服务器侦听连接(这是我拥有的移动游戏的基本高分服务器),每1000毫秒循环一次连接并侦听任何传入的数据。

public void readData(Connection c) throws IOException {
    PacketBuffer readBuffer = new PacketBuffer(Server.PACKET_CAPACITY);
    int packetSize = c.getIn().read();
    c.getIn().mark(packetSize);
    byte[] buffer = new byte[packetSize];
    c.getIn().read(buffer, 0, buffer.length);
    readBuffer.setBuffer(buffer);
    packetHandler.addProcess(c, readBuffer);
}

我使用自己的PacketBuffer,我需要找到一种方法来使c.getIn()。read()(这是我的输入InputStream)不会被阻塞。 当前套接字设置为500毫秒超时,我的服务器可以正常运行。 我的问题是,如果有人尝试创建自己的程序进行连接以尝试破解自己的高分或ddos服务器,则它将被一堆无用的连接所困扰,这些连接在不写入时会阻塞线程500ms。

您可以尝试这样的事情。 每次调用readData时,它将检查是否可以读取字节。 这里使用了while循环,因为您希望它在线程再次休眠之前处理所有可以处理的数据。 如果每x毫秒只读取一次,这将确保不备份邮件。

public void readData(Connection c) throws IOException {
    while (c.getIn().available() > 0) {
        int packetSize = c.getIn().read();
        c.getIn().mark(packetSize);
        byte[] buffer = new byte[packetSize];
        c.getIn().read(buffer, 0, buffer.length);
        PacketBuffer readBuffer = new PacketBuffer(Server.PACKET_CAPACITY);
        readBuffer.setBuffer(buffer);
        packetHandler.addProcess(c, readBuffer);
    }

我不知道您为什么使用mark方法。 对我来说似乎有问题。

您还真的需要使用readFully()样式方法(请参见DataInputStream),直到确定地读取了完整的字节数组,该方法才返回。 即使发件人发送了完整的数据块(由于网络数据包大小等),常规读取也总是可以“返回短”。

有两种用Java实现服务器的经典方法。

第一种也是最古老的方法是为每个连接的客户端使用读/写线程对。 对于没有大量客户端连接的小型服务器,这是可以的,因为每个客户端都需要两个线程来管理它。 它不能很好地扩展到许多并发客户端。

第二种更新的方法是使用java.nio.ServerSocketChanneljava.nio.SocketChanneljava.nio.Selector 这三个类使您可以管理在单个线程中连接的每个客户端的所有IO操作。 是一个有关如何使用java.nio包实现非常基本的服务器的示例。

实施服务器的更好方法是使用第三方框架。 我过去使用过的一个很棒的库是Netty 它处理套接字的所有细节,并提供了一个相当干净和简单的api,可以很好地扩展。

你不能 InputStreams正在阻塞。 期。 很难看到非阻塞模式将如何真正解决您提到的问题。 我建议重新设计。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM