Results 1 to 2 of 2
  1. #1
    Fortu is offline Member
    Join Date
    Dec 2010
    Posts
    57
    Rep Power
    0

    Default Client/Server Optimization

    Look below for the actual server and client communication. The client can't run on it's own, but the important part is figuring out why the server can get positions so quickly, but they can't be sent back to the clients with as much speed.

    Hello. I've recently gone through the Java networking trail and a few other networking tutorials, and I'm starting to get a decent grasp on it, so I went right ahead and made myself a multiplayer game for LAN (because I don't know how to connect over internet yet) but now I have some optimization questions, because my server is sending clients the integers which represent the positions of other clients way too slowly to be acceptable.

    I'll be playing this barebones version of my game and checking my command prompt (windows) to watch the coords of my character or another get updated, but I notice that it's at least 20 seconds after when I stopped moving that the coordinates finally catch up, and more depending on how much I move. It's upacceptable for a multiplayer game.

    I'll post a SSCCE (which will just be the source code of it all wrapped up in a ZIP file anyway, because there's no way to take any of this out), and I was hoping one of you kind people could help me work my way through this nasty slowness, and thank you everyone who looks at this, even if you don't come up with any solutions for me :)

    Game.zip
    Last edited by Fortu; 04-20-2011 at 12:39 AM.

  2. #2
    Fortu is offline Member
    Join Date
    Dec 2010
    Posts
    57
    Rep Power
    0

    Default

    No one seems to want to go through all of my code to see what's really there, so I'll post this here as a follow-up. Maybe people will actually try to help when there's not so much to look at and it's not a download. Anyway, I'll start posting direct server to client code that I wrote. The actual game isn't important. Here comes the server code. This class can be skipped over if you only want to look at direct communication.

    Java Code:
    import java.io.*;
    import java.net.*;
    import java.util.ArrayList;
    import javax.swing.Timer;
    import java.awt.event.*;
    
    public class Server implements ActionListener
    {
    
      public ServerSocket server;
      public ArrayList<ServerThread> clients;
      public ArrayList<Integer> coords;
      public Timer timer;
    
      public Server()
      {
        clients = new ArrayList<ServerThread>();
        coords = new ArrayList<Integer>();
        try
        {
          server = new ServerSocket(9001);
        }
        catch(Exception e)
        {
          e.printStackTrace();
        }
        timer = new Timer(400,this);
        timer.start();
      }
    
      public void accept()
      {
        while(true)
        {
          try
          {
            ServerThread thread = new ServerThread(server.accept());
    	clients.add(thread);
    	thread.start();
          }
          catch(Exception e1)
          {
            e1.printStackTrace();
          }
        }
      }
    
      public void disconnect() //method that allows clients to disconnect without causing errors
      // for the server.. Most of the time.
      {
        try{
          for(int i=0;i<clients.size();i++)
          {
            if(clients.get(i).isDisconnect())
            {
    	  try
    	  {
    	    clients.get(i).closeAll();
    	   clients.remove(i);
    	  }
    	  catch(Exception e3)
    	  {
    	   e3.printStackTrace();
    	  }
            }
          }
        }
        catch(Exception e40)
        {
          e40.printStackTrace();
        }
      }
    
      public void coords()
      {
        if(coords.size()<(clients.size()*3))
        {
          int y = (clients.size()*3)-coords.size();
          while(y>0)
          {
    	coords.add(new Integer(0));
    	y--;
          }
        }
    
        if(coords.size()>(clients.size()*3) && clients.size() != 0)
        {
          int c = coords.size()-(clients.size()*3);
          while(c>0)
          {
    	coords.subList((coords.size()-c),coords.size()).clear();
          }
        }
          
        for(int i = 0;i<clients.size();i++)
        {
          ArrayList<Integer> array = clients.get(i).getCoords();
          for(int u = 0;u<array.size();u++)
          {
    	coords.set(i*3+u,array.get(u));
          }
        }
      }
    
      public void actionPerformed(ActionEvent ae) // right here is where all of this takes place
      {
        for(int i=0;i<clients.size();i++)
        {
          clients.get(i).update(i+1);
          System.out.println(clients.get(i).getSocket());
          clients.get(i).print();
          clients.get(i).getCoords(coords);
        }
        try
        {
          coords();
        }
        catch(Exception e10)
        {
          e10.printStackTrace();
        }
        disconnect();
        for(int g = 0;g<coords.size();g++)
        {
          System.out.print(coords.get(g) + " ");
        }
      }
    
      public static void main(String[] args)
      {
        Server server = new Server();
        server.accept();
      }
    }
    Right here is the ServerThread class. It does the actual communication between the client and the server, and the server's only purpose is to put all the data together into one ArrayList package, update all threads with that arraylist, and accept and disconnect clients.

    Java Code:
    import java.net.*;
    import java.io.*;
    import java.util.ArrayList;
    import java.util.Random;
    
    public class ServerThread extends Thread
    {
    
      public Socket socket;
      public DataInputStream in;
      public DataOutputStream out;
      public ObjectOutputStream oos;
      public int x = 0;
      public int y = 0;
      public boolean disconnect;
      public boolean cont;
      public int num;
      public ArrayList<Integer> awesome;
      public boolean wait = false;
      public Random random;
    
      public ServerThread(Socket socket)
      {
        this.socket = socket;
        cont = true;
        disconnect = false;
        awesome = new ArrayList<Integer>();
        try
        {
          in = new DataInputStream(this.socket.getInputStream());
          out = new DataOutputStream(this.socket.getOutputStream());
          oos = new ObjectOutputStream(this.socket.getOutputStream());
          random = new Random();
        }
        catch(Exception e)
        {
          try
          {
            in.close();
            out.close();
    	oos.close();
          }
          catch(Exception e1)
          {
    	e1.printStackTrace();
          }
          e.printStackTrace();
        }
      }
    
      public void update(int num)
      {
        this.num = num;
      }
    
      public void getCoords(ArrayList<Integer> array)
      {
        awesome = array;
      }
    
      public void print()
      {
        System.out.println("I'm thread " + num);
      }
    
      public void closeAll() throws Exception
      {
        out.writeByte(5);
        cont = false;
      }
    
      public boolean isDisconnect()
      {
        return disconnect;
      }
    
      public Socket getSocket()
      {
        return socket;
      }
    
      public void stop(boolean b)
      {
        this.cont = b;
      }
    
      public ArrayList<Integer> getCoords()
      {
        ArrayList<Integer> array = new ArrayList<Integer>();
        array.add(new Integer(num));
        array.add(new Integer(x));
        array.add(new Integer(y));
        return array;
      }
    
      public ArrayList getArray()
      {
        return awesome;
      }
    
      public void run()
      {
        while(cont)
        {
          try
          {
    	int b = in.readByte();
            if(b == 2)
            {
    	  x = in.readInt();
    	  //System.out.println(x);
            }
            if(b == 3)
            {
    	  y = in.readInt();
    	  //System.out.println(y);
            }
    	if(b == 4)
    	{
    	  disconnect = true;
    	}
    	out.writeBoolean(true);
    	oos.writeUnshared((Object)awesome);
    	while(!wait)
    	{
    	  wait = in.readBoolean();
    	}
          }
          catch(Exception ie)
          {
    	ie.printStackTrace();
          }
        }
        try
        {
          in.close();
          out.close();
          oos.close();
          socket.close();
        }
        catch(Exception e)
        {
          e.printStackTrace();
        }
      }
    }
    Here's the client. Know that in my game I have a util timer scheduling this code to be run once every 250 seconds, but it gets scheduled after scheduling another TimerTask which give the player's current positions to the client, and then the client sends them to the server and gets an arraylist back of all player coordinates.
    The Client:

    Java Code:
    import java.io.*;
    import java.net.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    
    public class Client extends TimerTask
    {
    
      public Socket socket;
      public DataInputStream in;
      public DataOutputStream out;
      public ObjectInputStream ois;
      public int x;
      public int y;
      public int stop;
      public boolean wait = false;
      public boolean cont = true;
      public int number;
      public ArrayList others;
    
      public Client()
      {
        others = new ArrayList();
        try
        {
          socket = new Socket("192.168.1.102",9001);
          in = new DataInputStream(socket.getInputStream());
          out = new DataOutputStream(socket.getOutputStream());
          ois = new ObjectInputStream(socket.getInputStream());
        }
        catch(Exception e)
        {
          e.printStackTrace();
          System.exit(0);
        }
        if(socket.isConnected())
        {
          System.out.println("Dude you connected!");
        }
      }
    
      public void setX(int x)
      {
        this.x = x;
      }
    
      public void setY(int y)
      {
        this.y = y;
      }
    
      public void incX()
      {
        x++;
      }
    
      public void incY()
      {
        y++;
      }
    
      public void disconnect() throws IOException
      {
        out.writeByte(4);
        cont = false;
        while(!(in.readByte() == 5))
        {
        }
        in.close();
        out.close();
        ois.close();
        socket.close();
        System.exit(0);
      }
    
      public ArrayList getOthers()
      {
        return others;
      }
    
      public void communicate() throws IOException, ClassNotFoundException
      {
        out.writeByte(2);
        out.writeInt(x);
        out.writeByte(3);
        out.writeInt(y);
        while(!wait)
        {
          wait = in.readBoolean();
        }
        wait = false;
        others = (ArrayList)ois.readUnshared();
        out.writeBoolean(true);
      }
    
      public void run()
      {
        if(cont)
        {
          try
          {
    	communicate();
          }
          catch(Exception e)
          {
    	e.printStackTrace();
          }
        }
      }
    }
    Lastly, thanks for looking at this if you do :)

Similar Threads

  1. Replies: 2
    Last Post: 09-24-2010, 12:31 PM
  2. Replies: 3
    Last Post: 07-29-2009, 05:52 AM
  3. Replies: 7
    Last Post: 12-16-2008, 07:44 PM
  4. Replies: 1
    Last Post: 10-05-2008, 04:12 PM
  5. Identify Client in Socket Client Server Application
    By masadjie in forum Networking
    Replies: 1
    Last Post: 12-20-2007, 10:18 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •