我试图做一个简单的网络客户端。客户端应该能够写入一个队列(缓冲区),第二个线程应该把这个缓冲区写入服务器。试图填充缓冲区,同时缓冲区写入通道
我用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