我試圖做一個簡單的網絡客戶端。客戶端應該能夠寫入一個隊列(緩衝區),第二個線程應該把這個緩衝區寫入服務器。試圖填充緩衝區,同時緩衝區寫入通道
我用java.nio
試了一下,並用靜態ByteBuffer
創建了Thread
。 ByteBuffer
正用於Thread
的while(true)
中,用於寫入通道。
在我的主循環中,我通過put()
方法將一些字節放入靜態緩衝區。
在調試模式下,我暫停了通道寫入線程,然後通過主程序循環填充緩衝區(只需將'A'寫入緩衝區)。
在三個或四個按鈕按下後,我再次啓動通道寫入線程,它工作得很好。
但是,當我正常嘗試程序時,我在主循環線程中出現緩衝區溢出錯誤。我相信我的程序正試圖將數據放入緩衝區,同時通過我的通道寫入線程訪問緩衝區。我試圖在兩個線程的兩個部分中使用synchronized關鍵字,但這並沒有幫助。
主迴路:
[...]
if(Gdx.app.getInput().isKeyPressed(Input.Keys.A) && (now.getTime() - lastPush.getTime()) > 1000)
{
lastPush = now;
//synchronized (PacketReader.writeBuffer)
//{
PacketReader.writeBuffer.put(("KeKe").getBytes());
//}
}
[...]
我的主題命名爲 「PacketReader」(以及它的實際讀,寫):
class PacketReader implements Runnable
{
public static ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
[...]
public void run()
{
while (true) {
[...]
if (selKey.isValid() && selKey.isWritable())
{
SocketChannel sChannel = (SocketChannel)selKey.channel();
//synchronized (PacketReader.writeBuffer)
//{
if(PacketReader.writeBuffer.hasRemaining())
{
PacketReader.writeBuffer.flip();
int numBytesWritten = sChannel.write(PacketReader.writeBuffer);
PacketReader.writeBuffer.flip();
}
//}
}
[...]
任何想法如何創建這樣一個緩衝的寫入系統?我認爲這是一個常見問題,但我不知道要搜索什麼。所有的NIO教程似乎認爲緩衝區在通道循環中被填滿。
最後我試圖有一個程序,其中網絡組件啓動一次,並在我的程序中,我只是想使用一些靜態發送方法發送數據包,而不考慮隊列處理或等待隊列。
是否有可能在某個地方的教程?大多數遊戲應該使用類似的概念,但是我找不到任何帶有NIO實現的開源簡單java遊戲(我將使用它用於android,所以我在沒有框架的情況下使用它)
謝謝您的建議。我一直在考慮像Kryonet或Pyronet這樣的Lightwight框架,但是當我在Android上使用這個框架時,我認爲直接編程對性能會更好。另一方面,我想學習NIO,那麼爲什麼不折磨自己呢? :D – 2012-01-10 14:55:23