I have a client/server java game im working on. There’s a bunch of code and im trying to paste as little as possible while still giving enough.
When I first start the server, it takes no CPU. When my first game client connects, it jumps to 25%(which seems quite high for what it does, but thats not my main concern yet). The problem is, even when the client disconnects, the CPU usage of the server app remains at 25%.
The server takes a name from the client and constantly receives x, y coordinates from the player.
Here is the code for my actual server that is run once the server is started: (I apologize beforehand for the excessive indentation)
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);
}
}
And here is code that is run for each client. I have commented out a large portion of it for readability, the code just calculates and updates various location information. I think the problem is occurring somewhere here in this class.
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);
}
}
}
And finally, a short class to write information to the client:
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);
}
}
}
I know there’s a ton of code but if somebody sees anyting that immediately jumps out (especially with the threads) that can explain the behavior im getting. To recap, the server stays at 0% cpu until a client connects. After the first client connects, no matter how many more connect, it stays from 25%-30% CPU. However, when all of the client have disconnected, the CPU STAYS at that 25%-30% instead of going back down to 0.
The problem is here:
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.