我正在尝试为Android设备创建一个简单的多人游戏。我一直在思考网络代码,现在阅读了很多有关套接字的页面。 Android应用程序将仅是客户端,并且仅连接到一台服务器。

由于“阻塞”,几乎在所有地方(这里也是)您都建议使用NIO或使用NIO的框架。
我试图了解一个简单的套接字实现的问题,所以我创建了一个简单的测试来尝试:

我的主要应用:

[...]
Socket clientSocket = new Socket( "127.0.0.1", 2593 );
new Thread(new PacketReader(clientSocket)).start();
PrintStream os = new PrintStream( clientSocket.getOutputStream() );
os.println( "kakapipipopo" );
[...]

PacketReader线程:
class PacketReader implements Runnable
{
    Socket m_Socket;
    BufferedReader m_Reader;

    PacketReader(Socket socket)
    {
        m_Reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    }

    public void run()
    {
        char[] buffer = new char[200];
        int count = 0;
        while(true)
        {
            count = m_Reader.read(buffer, 0, 200);
            String message = new String(buffer, 0, count);
            Gdx.app.log("keks", nachricht);
        }
    }
}

我没有遇到应该遇到的阻塞问题。我以为read()函数会阻止我的应用程序,但我什么也做不了-但一切正常。
我一直在想:如果我只是在应用程序中创建一个输入和输出缓冲区,并创建两个线程来从两个缓冲区中向套接字写入和读取,该怎么办?这行得通吗?
如果是,为什么每个人都推荐NIO?以正常的IO方式在某个地方一定会发生阻塞,但我找不到它。
使用NIO进行Android多人游戏还有其他好处吗?我认为NIO似乎更复杂,因此可能不太适合移动设备,但是简单的套接字方式对于移动设备而言更糟。

如果有人可以告诉我问题出在哪里,我将非常高兴。我不怕NIO,但至少我想知道为什么我要使用它:D

你好

-托马斯

最佳答案

阻塞是,read()将阻塞当前线程,直到它可以从套接字的输入流中读取数据为止。因此,您需要一个专用于该TCP连接的线程。

如果服务器连接了超过1万个客户端设备,该怎么办?无论它们是否处于 Activity 状态,您至少需要10k线程来处理所有客户端设备(假设每个设备都维护一个TCP连接)。您在上下文切换上有太多开销,而其他多线程开销甚至只有其中100个处于 Activity 状态。

NIO使用选择器模型来处理那些客户端,这意味着您不需要每个TCP连接都使用专用线程来接收数据。您只需要选择所有 Activity 连接(已接收到数据)并处理这些 Activity 连接即可​​。您可以控制应在服务器端维护多少个线程。

关于java - 为什么我应该使用NIO进行TCP多人游戏,而不是简单的套接字(IO)-或: where is the block?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8743628/

10-10 17:15