我正在开发一个客户端/服务器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。
答案 0 :(得分:5)
问题在于:
while(!clientList.get(z).cr.nameRecieved)
{
//do nothing untill client has provided it's name
}
这是一个抽取CPU的旋转循环。你这样做是错的。一旦接受了套接字,就必须启动一个新线程来处理它。 该线程应该阻止,直到客户端提供其名称作为协议握手的一部分,然后更新您的数据结构。除了接受连接和启动线程之外,accept循环不应该做任何事情。