[英]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.ServerSocketChannel
, java.nio.SocketChannel
和java.nio.Selector
。 這三個類使您可以管理在單個線程中連接的每個客戶端的所有IO操作。 這是一個有關如何使用java.nio
包實現非常基本的服務器的示例。
實施服務器的更好方法是使用第三方框架。 我過去使用過的一個很棒的庫是Netty 。 它處理套接字的所有細節,並提供了一個相當干凈和簡單的api,可以很好地擴展。
你不能 InputStreams正在阻塞。 期。 很難看到非阻塞模式將如何真正解決您提到的問題。 我建議重新設計。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.