0

我有一个正在开发的客户端/服务器 java 游戏。有一堆代码,我试图尽可能少地粘贴,同时仍然提供足够的内容。

当我第一次启动服务器时,它不需要 CPU。当我的第一个游戏客户端连接时,它会跃升至 25%(这似乎相当高,但这还不是我主要关心的问题)。问题是,即使客户端断开连接,服务器应用程序的 CPU 使用率仍保持在 25%。

服务器从客户端获取名称并不断从玩家那里接收 x、y 坐标。

这是我在服务器启动后运行的实际服务器的代码:(我事先为过度缩进道歉)

 TCPServer(int port) {
                try
                {
                        tcpSock = new ServerSocket(port);
                        int z = 0;
                        while(true)
                        {
                                Socket sock = tcpSock.accept();
                                sock.setKeepAlive(true);  
                                clientList.addElement(new TcpClient(sock));
                                clientList.get(z).cr.start();
                                clientList.get(z).cw.start();
                                clientList.get(z).packs.addElement("?");
                                while(!clientList.get(z).cr.nameRecieved)
                                {
                                //do nothing untill client has provided it's name
                                }
                                playerList.addElement(new player(sock.getInetAddress(), clientList.get(z).cr.playerName));                                     
                                playerList.get(z).id=z;
                                playerList.get(z).name=clientList.get(z).cr.playerName;
                                clientList.get(z).packs.addElement("2 " + z);
                                for(int j =0; j<playerList.size();j++)
                                    {
                                   String status;
                                   if(playerList.get(j).Connected)
                                       status = "1";
                                   else
                                       status = "0";

                                        addToQueue("3 " + playerList.get(j).id + " "
                                                + playerList.get(j).name + " " + playerList.get(j).x + " " + playerList.get(j).y + " " + 
                                                playerList.get(j).area + " " + status + " " );                     
                                    }
                                z++;
                                addToQueue("4 " + z);
                        }    
                }

                catch (IOException e) {   
                        System.out.print(e);   
                }   
        }

这是为每个客户端运行的代码。为了便于阅读,我已经注释掉了大部分内容,代码只是计算和更新各种位置信息。我认为这个问题发生在这个班级的某个地方。

  public class TcpClient {
                Socket sock;
                ObjectInputStream in;
                ObjectOutputStream out;
                ClientRead cr;
                ClientWrite cw;
                public Vector<String> packs = new Vector<String>();
                 TcpClient(Socket s) {
                        this.sock = s;
                        try
                        {
                            sock.setKeepAlive(true);
                        }
                        catch(Exception e)
                        {
                            System.out.print(e);
                        }
                        cr = new ClientRead();
                        cw = new ClientWrite();
                }
                public class ClientRead extends Thread {
                     public boolean nameRecieved = false;
                     public boolean reading = true;
                String playerName;
                    public void run(){
                        try{
                            in  = new ObjectInputStream(sock.getInputStream());
                            while(sock.isConnected() && reading)
                            {
                               //code to retrieve and update user location
                            }
                        }
                        catch(Exception e){
                                System.out.print(e);
                    }
                }
        }

最后,一个向客户端写入信息的简短类:

public class ClientWrite extends Thread {
                 public boolean writing = true;
                    public void run() {
                        try{

                            out = new ObjectOutputStream(sock.getOutputStream());
                            out.flush();
                            while(sock.isConnected() && writing)
                            {
                                out.flush();
                                while(!packs.isEmpty())
                                {
                                    out.writeObject(packs.firstElement());
                                    System.out.print(packs.firstElement());
                                    packs.remove(0);
                                    out.flush();
                                }
                            }

                        }
                        catch(Exception e)
                        {
                            System.out.print(e);
                        }
                    }
                }

我知道有大量代码,但是如果有人看到任何立即跳出来的东西(尤其是线程),就可以解释我得到的行为。回顾一下,服务器保持在 0% cpu 直到客户端连接。在第一个客户端连接后,无论再连接多少,它都保持在 25%-30% 的 CPU 上。但是,当所有客户端都断开连接时,CPU 会停留在 25%-30%,而不是回到 0。

4

1 回答 1

5

问题在这里:

while(!clientList.get(z).cr.nameRecieved)
{
    //do nothing untill client has provided it's name
}

It is a spin loop that smokes the CPU. You're doing this all wrong. As soon as you have accepted the socket, you must start a new thread to handle it. That thread should block until the client has provided its name as part of your protocol handshake, and then update your data structures. The accept loop shouldn't do anything except accept connections and start threads.

于 2013-02-07T04:18:32.330 回答