Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (527)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (594)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  UDP woes? Or a logic error?  (Read 6166 times)
0 Members and 1 Guest are viewing this topic.
Offline CyanPrime
« Posted 2011-05-13 00:02:00 »

Okay, so player "B"'s X coord jumps between player "A"'s and it's own By player "B" I mean the non-client controlled player, and "A" is the player your client controls. So on client #2 player #1 would jump between player#2's X coord and it's own. My test case is a little big, but it's the bare minimum to reproduce the bug. also it requires Slick2d.

How can I fix this bug?

Client:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;


import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

public class TestClient extends BasicGame{
   ClientThread ct;
   int playerNum = 0;
   int[] playerX;
   int[] enemy;
   
   public  TestClient()
    {
        super("Test Client");
    }
   
   public static void main(String[] args)
   throws SlickException
   {
       AppGameContainer app =
         new AppGameContainer(new TestClient());
     
       app.setDisplayMode(640, 480, false);
       app.setTargetFrameRate(60);
       app.start();
   }

   @Override
   public void render(GameContainer gc, Graphics g) throws SlickException {
      g.fillRect(playerX[0], 0, 50, 50);
      g.fillRect(playerX[1], 0, 50, 50);
      g.drawString("px:" + playerX[playerNum], 10, 10);
      g.drawString("ex:" + playerX[enemy[playerNum]], 10, 25);
      g.drawString("p#:" + playerNum, 10, 40);
   }

   @Override
   public void init(GameContainer gc) throws SlickException {
      playerX = new int[2];
      playerX[0] = 50;
      playerX[1] = 200;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
      ct = new ClientThread(playerX);
        ct.start();
        ct.setPriority(Thread.MAX_PRIORITY);
       
        playerNum = ct.playerNum;
   }

   @Override
   public void update(GameContainer gc, int delta) throws SlickException {
      Input input = gc.getInput();
       if(input.isKeyDown(Input.KEY_A))
           {
               playerX[playerNum]-=2;
           }
   
           if(input.isKeyDown(Input.KEY_D))
           {
              playerX[playerNum]+=2;
           }
   }
}

class ClientThread extends Thread implements Runnable{
   DatagramSocket socket;
   DatagramPacket packet;
   int playerNum;
   int playerX[];
   int[] enemy;
    boolean loop = true;
    int port;
    byte [] addr;
    InetAddress address;
   
   public ClientThread(int playerX[]){
      super("ClientThread");
     
      this.playerX = playerX;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
     
      try{
         port = 4444;
          addr = new byte[] {(byte) 76,(byte) 121,(byte) 76,(byte) 188};
          address = InetAddress.getByAddress(addr);
         
          byte[] buf = new byte[10];
          socket = new DatagramSocket();
          DatagramPacket packet = new DatagramPacket(buf, 10, address, 4444);
         System.out.println("send" + address.toString());
         socket.send(packet);
         
         byte[] buf2 = new byte[255];
         packet = new DatagramPacket(buf2, buf2.length);
         socket.receive(packet);
         ByteBuffer receiveBuf = ByteBuffer.wrap(packet.getData());
         this.playerNum  = receiveBuf.getInt();
         System.out.println("#:"+this.playerNum);
         
         
      }
     
      catch(Exception e){
         e.printStackTrace();
      }
   }
   
   public void run(){
      try{
         while(loop){
           
            try{
               ByteBuffer sendBuf = ByteBuffer.allocate(255);
               sendBuf.putInt(playerX[playerNum]);
               
               DatagramPacket packet = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
               System.out.println("send" + address.toString());
               socket.send(packet);
               System.out.println("sent");
               
               byte[] buf = new byte[255];
               packet = new DatagramPacket(buf, buf.length);
               socket.receive(packet);
               ByteBuffer receiveBuf = ByteBuffer.wrap(packet.getData());
               playerX[enemy[playerNum]] = receiveBuf.getInt();
               System.out.println("playerX[enemy[playerNum]] "+playerX[enemy[playerNum]] );
               this.sleep(1);
              }
            catch(Exception e){
                   e.printStackTrace();
                   //socket.close();
             }  
         }
         
         
         
      }
     
      catch(Exception e){
         e.printStackTrace();
      }
   }
}


Server:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;


public class TestServer {
   static DatagramSocket socket;
   static int[] playerX;
   public void doStuff(){
      int MAX_PLAYERS = 2;
       int playerNum = 0;
       playerX = new int[2];
       byte [] addr = new byte[] {(byte) 0,(byte) 0,(byte) 0,(byte) 0};
       
       InetAddress player1IP = null;
       try {
         player1IP = InetAddress.getByAddress(addr);
      } catch (UnknownHostException e2) {
         // TODO Auto-generated catch block
         e2.printStackTrace();
      }
        int player1Port = -1;
       boolean listening = true;
       
        try {
         socket = new DatagramSocket(4444);
      } catch (SocketException e1) {
         // TODO Auto-generated catch block
         e1.printStackTrace();
      }
       
        while(playerNum < 2){
           
              byte[] buf = new byte[255];
               DatagramPacket packet = new DatagramPacket(buf, buf.length);
               System.out.println("Waiting for packet from player: " + playerNum + "\n");
             
             
               
               try {
               socket.receive(packet);
            } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
             
            if(packet.getAddress().toString().compareTo(player1IP.toString()) != 0 || packet.getPort() != player1Port){
                  if(playerNum == 0){
                     player1IP = packet.getAddress();
                     player1Port = packet.getPort();
                  }
             
           
              System.out.println("Waiting to connect with player: " + playerNum + "\n");
              new ClientThread(this, socket, packet,playerNum, playerX).start();
              //stops here.
              System.out.println("Connected with player: " + playerNum + " Now incrementing" + "\n");
              playerNum++;
              System.out.println("Incremented to: " + playerNum+ "\n");
           }
        }
       
        while(true){}
       
   }
   
   public static void main(String[] args){
      TestServer t = new TestServer();
      t.doStuff();
        //serverSocket.close();
       // System.exit(0);
   }
}


Client thread (Server)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;

public class ClientThread extends Thread implements Runnable{
   int playerNum;
   int enemy[];
   DatagramSocket socket;
   InetAddress address;
   TestServer ts;
   int port;
   public ClientThread(TestServer ts, DatagramSocket socket, DatagramPacket packet, int playerNum, int playerX[]){
      super("ClientThread");
     
      address = packet.getAddress();
      port = packet.getPort();
      this.socket = socket;
      this.playerNum = playerNum;
      this.ts = ts;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
     
      ByteBuffer sendBuf = ByteBuffer.allocate(255);
      System.out.println("#:"+playerNum);
      sendBuf.putInt(playerNum);
      DatagramPacket packet2 = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
      try {
         socket.send(packet2);
      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
   
   public void run(){
      try{
         System.out.println("Thread" + playerNum + ": " + "Accepted. Now creating I/O.\n");
           
           while(true){
              byte[] buf = new byte[255];
              DatagramPacket packet = new DatagramPacket(buf, buf.length);
               socket.receive(packet);
             
              ByteBuffer recieveBuf = ByteBuffer.wrap(packet.getData());
              //System.out.println("Threadxx#"+playerNum+": x:" + recieveBuf.getInt());
           
              ts.playerX[playerNum] = recieveBuf.getInt();
            //System.out.println("Thread#"+playerNum+": x:" + recieveBuf.getInt());
           
            ByteBuffer sendBuf = ByteBuffer.allocate(255);
           
            sendBuf.putInt(ts.playerX[enemy[playerNum]]);
            System.out.println("Thread#"+playerNum+": ex:" + ts.playerX[enemy[playerNum]]);
            DatagramPacket packet2 = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
            socket.send(packet2);
           
             this.sleep(1);
           }

      }
     
      catch(Exception e){
         e.printStackTrace();
         System.exit(1);
      }
       
       
   }
   
}
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #1 - Posted 2011-05-13 00:30:56 »

Could you be more clear? I'm having trouble understanding.

Sounds kind of like it's just a latency issue though. Generally I store one position old on the client and I interpolate between positions so it looks smooth. Also for unreliable networking protocols, store the date the most recent packet was sent and don't respond to any packets that were sent older than that.

See my work:
OTC Software
Offline CyanPrime
« Reply #2 - Posted 2011-05-13 01:11:21 »

Well, I don't think it's a latency issue. Anyway I'll try to explain it more clearly. If you're running on the second client to connect to the server you'll control player #2. In this case player #1 will jump between the position it's suppose to be in (It's own x) and where player #2 is.

Likewise if you're on the first client to connect to the server you will be in control of player #1 and you'll see player #2 messing up.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2011-05-13 05:01:37 »

Maybe you are incorrectly setting some variables somewhere? Accidentally setting player #1's position as player #2?

Offline CyanPrime
« Reply #4 - Posted 2011-05-13 05:35:20 »

Nope. I triple checked both the client and server, and that doesn't ever happen.
Offline CyanPrime
« Reply #5 - Posted 2011-05-13 18:17:41 »

Okay I fixed the bug where the X's got mixed up thanks to Kev, but now I'm getting awful lag. Can someone take a look and tell me why it's so laggy, or give me some tips on how to speed it up?

Server
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;


public class TestServer {
   static DatagramSocket socket;
   static int[] playerX;
   public void doStuff(){
      int MAX_PLAYERS = 2;
       int playerNum = 0;
       playerX = new int[2];
       byte [] addr = new byte[] {(byte) 0,(byte) 0,(byte) 0,(byte) 0};
       
       InetAddress player1IP = null;
       try {
         player1IP = InetAddress.getByAddress(addr);
      } catch (UnknownHostException e2) {
         // TODO Auto-generated catch block
         e2.printStackTrace();
      }
        int player1Port = -1;
       boolean listening = true;
       
        try {
         socket = new DatagramSocket(4444);
      } catch (SocketException e1) {
         // TODO Auto-generated catch block
         e1.printStackTrace();
      }
       
        while(playerNum < 2){
           
              byte[] buf = new byte[255];
               DatagramPacket packet = new DatagramPacket(buf, buf.length);
               System.out.println("Waiting for packet from player: " + playerNum + "\n");
             
             
               
               try {
               socket.receive(packet);
            } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
             
            if(packet.getAddress().toString().compareTo(player1IP.toString()) != 0 || packet.getPort() != player1Port){
                  if(playerNum == 0){
                     player1IP = packet.getAddress();
                     player1Port = packet.getPort();
                  }
             
           
              System.out.println("Waiting to connect with player: " + playerNum + "\n");
              new ClientThread(this, socket, packet,playerNum, playerX).start();
              //stops here.
              System.out.println("Connected with player: " + playerNum + " Now incrementing" + "\n");
              playerNum++;
              System.out.println("Incremented to: " + playerNum+ "\n");
           }
        }
       
        while(true){}
       
   }
   
   public static void main(String[] args){
      TestServer t = new TestServer();
      t.doStuff();
        //serverSocket.close();
       // System.exit(0);
   }
}


Client Thread (Server)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;

public class ClientThread extends Thread implements Runnable{
   int playerNum;
   int enemy[];
   DatagramSocket socket;
   InetAddress address;
   TestServer ts;
   int port;
   public ClientThread(TestServer ts, DatagramSocket socket, DatagramPacket packet, int playerNum, int playerX[]){
      super("ClientThread");
     
      address = packet.getAddress();
      port = packet.getPort();
      this.socket = socket;
      this.playerNum = playerNum;
      this.ts = ts;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
     
      ByteBuffer sendBuf = ByteBuffer.allocate(255);
      System.out.println("#:"+playerNum);
      sendBuf.putInt(playerNum);
      DatagramPacket packet2 = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
      try {
         socket.send(packet2);
      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
   
   public void run(){
      try{
         System.out.println("Thread" + playerNum + ": " + "Accepted. Now creating I/O.\n");
           
           while(true){
              byte[] buf = new byte[255];
              DatagramPacket packet = new DatagramPacket(buf, buf.length);
               socket.receive(packet);
             
              ByteBuffer recieveBuf = ByteBuffer.wrap(packet.getData());
              //System.out.println("Threadxx#"+playerNum+": x:" + recieveBuf.getInt());
              int tempPlayerNum = recieveBuf.getInt();
             
              if(tempPlayerNum == playerNum)
                 ts.playerX[playerNum] = recieveBuf.getInt();
            //System.out.println("Thread#"+playerNum+": x:" + recieveBuf.getInt());
           
            ByteBuffer sendBuf = ByteBuffer.allocate(255);
           
            sendBuf.putInt(enemy[playerNum]);
            sendBuf.putInt(ts.playerX[enemy[playerNum]]);
            System.out.println("Thread#"+playerNum+": ex:" + ts.playerX[enemy[playerNum]]);
            DatagramPacket packet2 = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
            socket.send(packet2);
           
             this.sleep(1);
           }

      }
     
      catch(Exception e){
         e.printStackTrace();
         System.exit(1);
      }
       
       
   }
   
}


client:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;


import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

public class TestClient extends BasicGame{
   ClientThread ct;
   int playerNum = 0;
   int[] playerX;
   int[] enemy;
   
   public  TestClient()
    {
        super("Test Client");
    }
   
   public static void main(String[] args)
   throws SlickException
   {
       AppGameContainer app =
         new AppGameContainer(new TestClient());
     
       app.setDisplayMode(640, 480, false);
       app.setTargetFrameRate(60);
       app.setAlwaysRender(true);
       app.start();
   }

   @Override
   public void render(GameContainer gc, Graphics g) throws SlickException {
      g.fillRect(playerX[0], 0, 50, 50);
      g.fillRect(playerX[1], 0, 50, 50);
      g.drawString("px:" + playerX[playerNum], 10, 10);
      g.drawString("ex:" + playerX[enemy[playerNum]], 10, 25);
      g.drawString("p#:" + playerNum, 10, 40);
   }

   @Override
   public void init(GameContainer gc) throws SlickException {
      playerX = new int[2];
      playerX[0] = 50;
      playerX[1] = 200;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
      ct = new ClientThread(playerX);
        ct.start();
        ct.setPriority(Thread.MAX_PRIORITY);
       
        playerNum = ct.playerNum;
   }

   @Override
   public void update(GameContainer gc, int delta) throws SlickException {
      Input input = gc.getInput();
       if(input.isKeyDown(Input.KEY_A))
           {
               playerX[playerNum]-=2;
           }
   
           if(input.isKeyDown(Input.KEY_D))
           {
              playerX[playerNum]+=2;
           }
   }
}

class ClientThread extends Thread implements Runnable{
   DatagramSocket socket;
   DatagramPacket packet;
   int playerNum;
   int playerX[];
   int[] enemy;
    boolean loop = true;
    int port;
    byte [] addr;
    InetAddress address;
   
   public ClientThread(int playerX[]){
      super("ClientThread");
     
      this.playerX = playerX;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
     
      try{
         port = 4444;
          addr = new byte[] {(byte) 76,(byte) 121,(byte) 76,(byte) 188};
          address = InetAddress.getByAddress(addr);
         
          byte[] buf = new byte[10];
          socket = new DatagramSocket();
          System.out.println("port" + socket.getLocalPort());
          DatagramPacket packet = new DatagramPacket(buf, 10, address, 4444);
         System.out.println("send" + address.toString());
         socket.send(packet);
         
         byte[] buf2 = new byte[255];
         packet = new DatagramPacket(buf2, buf2.length);
         socket.receive(packet);
         ByteBuffer receiveBuf = ByteBuffer.wrap(packet.getData());
         this.playerNum  = receiveBuf.getInt();
         System.out.println("#:"+this.playerNum);
         
         
      }
     
      catch(Exception e){
         e.printStackTrace();
      }
   }
   
   public void run(){
      try{
         while(loop){
           
            try{
               ByteBuffer sendBuf = ByteBuffer.allocate(255);
               sendBuf.putInt(playerNum);
               sendBuf.putInt(playerX[playerNum]);
               
               DatagramPacket packet = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
               System.out.println("send" + address.toString());
               socket.send(packet);
               System.out.println("sent");
               
               byte[] buf = new byte[255];
               packet = new DatagramPacket(buf, buf.length);
               socket.receive(packet);
               ByteBuffer receiveBuf = ByteBuffer.wrap(packet.getData());
               int tempEnemyNum = receiveBuf.getInt();
               
               if(enemy[playerNum] == tempEnemyNum ){
                  playerX[enemy[playerNum]] = receiveBuf.getInt();
                  System.out.println("playerX[enemy[playerNum]] "+playerX[enemy[playerNum]] + " p" + socket.getLocalPort()+"ten"+ tempEnemyNum);
               }
                  this.sleep(1);
              }
            catch(Exception e){
                   e.printStackTrace();
                   //socket.close();
             }  
         }
         
         
         
      }
     
      catch(Exception e){
         e.printStackTrace();
      }
   }
}
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #6 - Posted 2011-05-13 20:59:23 »

It looks perfectly fine to me. However, why do you extends Thread and implement Runnable? You only need Thread, no need for Runnable.

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #7 - Posted 2011-05-13 21:45:09 »

Yes, it's no big deal, but it is redundant.

Quote from: javadoc
java.lang
Class Thread

java.lang.Object
  java.lang.Thread
All Implemented Interfaces:
Runnable

Your lag could be caused by the while(true){} in TestServer, it's going to take a lot of resources from the server that can't go out to your client threads. You should put a sleep in there, at the very least.

Also, I think your overall design is not the best way of doing this. A lot of sleeping loops is pretty unreliable. Instead I'd put a fixed timestep loop on the client and server (with the same timestep). This is generally much better for networked games.

See my work:
OTC Software
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #8 - Posted 2011-05-13 21:56:04 »

He does sleep, albeit for 1 millisecond. Maybe 5-10 milliseconds could help.

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #9 - Posted 2011-05-13 21:56:49 »

He does sleep, albeit for 1 millisecond. Maybe 5-10 milliseconds could help.
No he does.

while(true){}

There is no sleep in between the braces. He sleeps in other places.

See my work:
OTC Software
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline CyanPrime
« Reply #10 - Posted 2011-05-13 22:02:17 »

fixed timestep loop? You mean using the Timer class?
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #11 - Posted 2011-05-13 22:14:24 »

Whoa, yeah what's that "while(true) {}" line for?!?
And I discourage the use of Swing Timer, use the Util Timer Smiley

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #12 - Posted 2011-05-13 22:20:37 »

fixed timestep loop? You mean using the Timer class?
No, I'd definitely avoid using that as well. A fixed timestep loop is one that updates logic a fixed number of times per minute, rather than going as fast as it possibly can. Usually I will have fixed game updates of only about 20 or 25 / second, and then let the FPS (rendering only) go as fast as it can and interpolate it.

Hm actually I've had a fixed timestep demo for a while that I haven't put anywhere. I'll put it in tutorials and link it...

See my work:
OTC Software
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #13 - Posted 2011-05-14 00:16:10 »

Here go you:

http://www.java-gaming.org/topics/game-loops/24220/view.html

See my work:
OTC Software
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #14 - Posted 2011-05-14 03:41:39 »

<3

Offline CyanPrime
« Reply #15 - Posted 2011-05-14 03:51:02 »

Okay, I tried doing what Eli said, but now even though the clients connect they don't seem to update their position, or something. Maybe I'm doing the loop wrong?

Server:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;


public class TestServer {
   static DatagramSocket socket;
   static int[] playerX;
   private long lastFpsTime;
   private int fps;
   public void doStuff(){
      long lastLoopTime = System.nanoTime();
        final long OPTIMAL_TIME = 1000000000 / 60; //60fps is optimal
     
      int MAX_PLAYERS = 2;
       int playerNum = 0;
       playerX = new int[2];
       byte [] addr = new byte[] {(byte) 0,(byte) 0,(byte) 0,(byte) 0};
       
       InetAddress player1IP = null;
       try {
         player1IP = InetAddress.getByAddress(addr);
      } catch (UnknownHostException e2) {
         // TODO Auto-generated catch block
         e2.printStackTrace();
      }
        int player1Port = -1;
       boolean listening = true;
       
        try {
         socket = new DatagramSocket(4444);
      } catch (SocketException e1) {
         // TODO Auto-generated catch block
         e1.printStackTrace();
      }
       
        while(playerNum < 2){
           
              byte[] buf = new byte[255];
               DatagramPacket packet = new DatagramPacket(buf, buf.length);
               System.out.println("Waiting for packet from player: " + playerNum + "\n");
             
             
               
               try {
               socket.receive(packet);
            } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
             
            if(packet.getAddress().toString().compareTo(player1IP.toString()) != 0 || packet.getPort() != player1Port){
                  if(playerNum == 0){
                     player1IP = packet.getAddress();
                     player1Port = packet.getPort();
                  }
             
           
              System.out.println("Waiting to connect with player: " + playerNum + "\n");
              new ClientThread(this, socket, packet,playerNum, playerX).start();
              //stops here.
              System.out.println("Connected with player: " + playerNum + " Now incrementing" + "\n");
              playerNum++;
              System.out.println("Incremented to: " + playerNum+ "\n");
           }
        }
       
        while(true){
           long now = System.nanoTime();
            long updateLength = now - lastLoopTime;
            lastLoopTime = now;
            //double delta = updateLength / ((double)OPTIMAL_TIME);
     
            // update the frame counter
            lastFpsTime += updateLength;
            fps++;
             
            // update our FPS counter if a second has passed since
            // we last recorded
            if (lastFpsTime >= 1000000000)
            {
                System.out.println("(FPS: "+fps+")");
                lastFpsTime = 0;
                fps = 0;
            }
           
            try {
               if((lastLoopTime-System.nanoTime())/1000000 + 10000 >= 0)
                  Thread.sleep( (lastLoopTime-System.nanoTime())/1000000 + 10000 );
         } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
        }
       
   }
   
   public static void main(String[] args){
      TestServer t = new TestServer();
      t.doStuff();
        //serverSocket.close();
       // System.exit(0);
   }
}


Client Thread (Server )
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
import java.io.IOException;
import java.net.*;
import java.nio.ByteBuffer;

public class ClientThread extends Thread implements Runnable{
   int playerNum;
   int enemy[];
   DatagramSocket socket;
   InetAddress address;
   TestServer ts;
   int port;
   private long lastLoopTime;
   private long lastFpsTime;
   private int fps;
   public ClientThread(TestServer ts, DatagramSocket socket, DatagramPacket packet, int playerNum, int playerX[]){
      super("ClientThread");
     
      address = packet.getAddress();
      port = packet.getPort();
      this.socket = socket;
      this.playerNum = playerNum;
      this.ts = ts;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
     
      ByteBuffer sendBuf = ByteBuffer.allocate(255);
      System.out.println("#:"+playerNum);
      sendBuf.putInt(playerNum);
      DatagramPacket packet2 = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
      try {
         socket.send(packet2);
      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
   
   public void run(){
      try{
         long lastLoopTime = System.nanoTime();
           final long OPTIMAL_TIME = 1000000000 / 60; //60fps is optimal
         
         System.out.println("Thread" + playerNum + ": " + "Accepted. Now creating I/O.\n");
           
           while(true){
             
              long now = System.nanoTime();
               long updateLength = now - lastLoopTime;
               lastLoopTime = now;
               //double delta = updateLength / ((double)OPTIMAL_TIME);
       
               // update the frame counter
               lastFpsTime += updateLength;
               fps++;
               
               // update our FPS counter if a second has passed since
               // we last recorded
               if (lastFpsTime >= 1000000000)
               {
                   System.out.println("(FPS: "+fps+")");
                   lastFpsTime = 0;
                   fps = 0;
               }
             
              byte[] buf = new byte[255];
              DatagramPacket packet = new DatagramPacket(buf, buf.length);
               socket.receive(packet);
             
              ByteBuffer recieveBuf = ByteBuffer.wrap(packet.getData());
              //System.out.println("Threadxx#"+playerNum+": x:" + recieveBuf.getInt());
              int tempPlayerNum = recieveBuf.getInt();
             
              if(tempPlayerNum == playerNum)
                 ts.playerX[playerNum] = recieveBuf.getInt();
            //System.out.println("Thread#"+playerNum+": x:" + recieveBuf.getInt());
           
            ByteBuffer sendBuf = ByteBuffer.allocate(255);
           
            sendBuf.putInt(enemy[playerNum]);
            sendBuf.putInt(ts.playerX[enemy[playerNum]]);
            System.out.println("Thread#"+playerNum+": ex:" + ts.playerX[enemy[playerNum]]);
            DatagramPacket packet2 = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
            socket.send(packet2);
           
            if((lastLoopTime-System.nanoTime())/1000000 + 10000 >= 0)
                     Thread.sleep( (lastLoopTime-System.nanoTime())/1000000 + 10000 );
           }

      }
     
      catch(Exception e){
         e.printStackTrace();
         System.exit(1);
      }
       
       
   }
   
}


Client:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;


import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

public class TestClient extends BasicGame{
   ClientThread ct;
   int playerNum = 0;
   int[] playerX;
   int[] enemy;
   
   public  TestClient()
    {
        super("Test Client");
    }
   
   public static void main(String[] args)
   throws SlickException
   {
       AppGameContainer app =
         new AppGameContainer(new TestClient());
     
       app.setDisplayMode(640, 480, false);
       app.setTargetFrameRate(60);
       app.setAlwaysRender(true);
       app.start();
   }

   @Override
   public void render(GameContainer gc, Graphics g) throws SlickException {
      g.fillRect(playerX[0], 0, 50, 50);
      g.fillRect(playerX[1], 0, 50, 50);
      g.drawString("px:" + playerX[playerNum], 10, 10);
      g.drawString("ex:" + playerX[enemy[playerNum]], 10, 25);
      g.drawString("p#:" + playerNum, 10, 40);
   }

   @Override
   public void init(GameContainer gc) throws SlickException {
      playerX = new int[2];
      playerX[0] = 50;
      playerX[1] = 200;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
      ct = new ClientThread(playerX);
        ct.start();
        ct.setPriority(Thread.MAX_PRIORITY);
       
        playerNum = ct.playerNum;
   }

   @Override
   public void update(GameContainer gc, int delta) throws SlickException {
      Input input = gc.getInput();
       if(input.isKeyDown(Input.KEY_A))
           {
               playerX[playerNum]-=2;
           }
   
           if(input.isKeyDown(Input.KEY_D))
           {
              playerX[playerNum]+=2;
           }
   }
}

class ClientThread extends Thread implements Runnable{
   DatagramSocket socket;
   DatagramPacket packet;
   int playerNum;
   int playerX[];
   int[] enemy;
    boolean loop = true;
    int port;
    byte [] addr;
    InetAddress address;
   private long lastFpsTime;
   private int fps;
   
   public ClientThread(int playerX[]){
      super("ClientThread");
     
      this.playerX = playerX;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
     
      try{
         port = 4444;
          addr = new byte[] {(byte) 76,(byte) 121,(byte) 76,(byte) 188};
          address = InetAddress.getByAddress(addr);
         
          byte[] buf = new byte[10];
          socket = new DatagramSocket();
          System.out.println("port" + socket.getLocalPort());
          DatagramPacket packet = new DatagramPacket(buf, 10, address, 4444);
         System.out.println("send" + address.toString());
         socket.send(packet);
         
         byte[] buf2 = new byte[255];
         packet = new DatagramPacket(buf2, buf2.length);
         socket.receive(packet);
         ByteBuffer receiveBuf = ByteBuffer.wrap(packet.getData());
         this.playerNum  = receiveBuf.getInt();
         System.out.println("#:"+this.playerNum);
         
         
      }
     
      catch(Exception e){
         e.printStackTrace();
      }
   }
   
   public void run(){
      try{
         long lastLoopTime = System.nanoTime();
           final long OPTIMAL_TIME = 1000000000 / 60; //60fps is optimal
         
         while(loop){
           
            long now = System.nanoTime();
               long updateLength = now - lastLoopTime;
               lastLoopTime = now;
               //double delta = updateLength / ((double)OPTIMAL_TIME);
       
               // update the frame counter
               lastFpsTime += updateLength;
               fps++;
               
               // update our FPS counter if a second has passed since
               // we last recorded
               if (lastFpsTime >= 1000000000)
               {
                   System.out.println("(FPS: "+fps+")");
                   lastFpsTime = 0;
                   fps = 0;
               }
           
            try{
               ByteBuffer sendBuf = ByteBuffer.allocate(255);
               sendBuf.putInt(playerNum);
               sendBuf.putInt(playerX[playerNum]);
               
               DatagramPacket packet = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
               System.out.println("send" + address.toString());
               socket.send(packet);
               System.out.println("sent");
               
               byte[] buf = new byte[255];
               packet = new DatagramPacket(buf, buf.length);
               socket.receive(packet);
               ByteBuffer receiveBuf = ByteBuffer.wrap(packet.getData());
               int tempEnemyNum = receiveBuf.getInt();
               
               if(enemy[playerNum] == tempEnemyNum ){
                  playerX[enemy[playerNum]] = receiveBuf.getInt();
                  System.out.println("playerX[enemy[playerNum]] "+playerX[enemy[playerNum]] + " p" + socket.getLocalPort()+"ten"+ tempEnemyNum);
               }
               
               if((lastLoopTime-System.nanoTime())/1000000 + 10000 >= 0)
                     Thread.sleep( (lastLoopTime-System.nanoTime())/1000000 + 10000 );
         
              }
            catch(Exception e){
                   e.printStackTrace();
                   //socket.close();
             }  
         }
         
         
         
      }
     
      catch(Exception e){
         e.printStackTrace();
      }
   }
}
Offline CyanPrime
« Reply #16 - Posted 2011-05-15 01:49:10 »

Okay I was told  in #lwjgl to make my client and server single threaded,  so I did and now i have a problem where the first client to connect to the server always freezes. Can anyone help me figure this out and fix it?

Server:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;


public class TestServer {
   static DatagramSocket socket;
   static int[] playerX;
   int enemy[];
   
   public void doStuff(){
      System.nanoTime();
        int playerNum = 0;
       playerX = new int[2];
       
       enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
       
       byte [] addr = new byte[] {(byte) 0,(byte) 0,(byte) 0,(byte) 0};
       
       InetAddress player1IP = null;
       try {
         player1IP = InetAddress.getByAddress(addr);
      } catch (UnknownHostException e2) {
         // TODO Auto-generated catch block
         e2.printStackTrace();
      }
        int player1Port = -1;
       try {
         socket = new DatagramSocket(4444);
      } catch (SocketException e1) {
         // TODO Auto-generated catch block
         e1.printStackTrace();
      }
       
        while(playerNum < 2){
           byte[] buf = new byte[255];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            System.out.println("Waiting for packet from player: " + playerNum + "\n");
           
           
           
            try {
            socket.receive(packet);
         } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
           
         if(packet.getAddress().toString().compareTo(player1IP.toString()) != 0 || packet.getPort() != player1Port){
               if(playerNum == 0){
                  player1IP = packet.getAddress();
                  player1Port = packet.getPort();
               }
           
         
               ByteBuffer sendBuf = ByteBuffer.allocate(255);
              System.out.println("#:"+playerNum);
              sendBuf.putInt(playerNum);
              DatagramPacket packet2 = new DatagramPacket(sendBuf.array(), sendBuf.array().length, packet.getAddress(), packet.getPort());
             
              try {
                 socket.send(packet2);
              } catch (IOException e) {
                 e.printStackTrace();
              }
             
              System.out.println("Connected with player: " + playerNum + " Now incrementing" + "\n");
              playerNum++;
              System.out.println("Incremented to: " + playerNum+ "\n");
         }
         
         else{
            System.out.println("player1 connected before player 2");
            serverLoop();
         }
        }
       
        while(true){
           serverLoop();
        }
   }
   
   public void serverLoop(){
      byte[] buf = new byte[255];
       DatagramPacket packet = new DatagramPacket(buf, buf.length);
        try {
         socket.receive(packet);
      } catch (IOException e1) {
         e1.printStackTrace();
      }
       
       ByteBuffer recieveBuf = ByteBuffer.wrap(packet.getData());
       //System.out.println("Threadxx#"+playerNum+": x:" + recieveBuf.getInt());
       int tempPlayerNum = recieveBuf.getInt();
       
       playerX[tempPlayerNum] = recieveBuf.getInt();
      //System.out.println("Thread#"+playerNum+": x:" + recieveBuf.getInt());
     
      ByteBuffer sendBuf = ByteBuffer.allocate(255);
     
      sendBuf.putInt(enemy[tempPlayerNum]);
      sendBuf.putInt(playerX[enemy[tempPlayerNum]]);
      System.out.println("tempPlayerNum#"+tempPlayerNum+": ex:" + playerX[enemy[tempPlayerNum]]);
      DatagramPacket packet2 = new DatagramPacket(sendBuf.array(), sendBuf.array().length, packet.getAddress(), packet.getPort());
      try {
         socket.send(packet2);
      } catch (IOException e) {
         e.printStackTrace();
      }
    }
   
   public static void main(String[] args){
      TestServer t = new TestServer();
      t.doStuff();
        //serverSocket.close();
       // System.exit(0);
   }
}


Client:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.ByteBuffer;


import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

public class TestClient extends BasicGame{
   int playerNum = 0;
   int[] playerX;
   int[] enemy;
   
   DatagramSocket socket;
   DatagramPacket packet;
   private InetAddress address;
   private byte[] addr;
   private int port;
   
   public  TestClient()
    {
        super("Test Client");
    }
   
   public static void main(String[] args)
   throws SlickException
   {
       AppGameContainer app =
         new AppGameContainer(new TestClient());
     
       app.setDisplayMode(640, 480, false);
       app.setTargetFrameRate(60);
       app.setAlwaysRender(true);
       app.start();
   }

   @Override
   public void render(GameContainer gc, Graphics g) throws SlickException {
      g.fillRect(playerX[0], 0, 50, 50);
      g.fillRect(playerX[1], 0, 50, 50);
      g.drawString("px:" + playerX[playerNum], 10, 10);
      g.drawString("ex:" + playerX[enemy[playerNum]], 10, 25);
      g.drawString("p#:" + playerNum, 10, 40);
   }

   @Override
   public void init(GameContainer gc) throws SlickException {
      playerX = new int[2];
      playerX[0] = 50;
      playerX[1] = 200;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
     
      try{
         port = 4444;
          addr = new byte[] {(byte) 76,(byte) 121,(byte) 76,(byte) 188};
          address = InetAddress.getByAddress(addr);
         
          byte[] buf = new byte[10];
          socket = new DatagramSocket();
          System.out.println("port" + socket.getLocalPort());
          DatagramPacket packet = new DatagramPacket(buf, 10, address, 4444);
         System.out.println("send" + address.toString());
         socket.send(packet);
         
         byte[] buf2 = new byte[255];
         packet = new DatagramPacket(buf2, buf2.length);
         socket.receive(packet);
         ByteBuffer receiveBuf = ByteBuffer.wrap(packet.getData());
         this.playerNum  = receiveBuf.getInt();
         System.out.println("#:"+this.playerNum);
         
         
      }
     
      catch(Exception e){
         e.printStackTrace();
      }
   }

   @Override
   public void update(GameContainer gc, int delta) throws SlickException {
      Input input = gc.getInput();
       if(input.isKeyDown(Input.KEY_A))
           {
               playerX[playerNum]-=2;
           }
   
           if(input.isKeyDown(Input.KEY_D))
           {
              playerX[playerNum]+=2;
           }
           
           ByteBuffer sendBuf = ByteBuffer.allocate(255);
         sendBuf.putInt(playerNum);
         sendBuf.putInt(playerX[playerNum]);
         
         DatagramPacket packet = new DatagramPacket(sendBuf.array(), sendBuf.array().length, address, port);
         System.out.println("send" + address.toString());
         try {
            socket.send(packet);
         } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
         System.out.println("sent");
         
         byte[] buf = new byte[255];
         packet = new DatagramPacket(buf, buf.length);
         try {
            socket.receive(packet);
         } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
         }
         ByteBuffer receiveBuf = ByteBuffer.wrap(packet.getData());
         int tempEnemyNum = receiveBuf.getInt();
         
         if(enemy[playerNum] == tempEnemyNum ){
            playerX[enemy[playerNum]] = receiveBuf.getInt();
            System.out.println("playerX[enemy[playerNum]] "+playerX[enemy[playerNum]] + " p" + socket.getLocalPort()+"ten"+ tempEnemyNum);
         }
   }
}
Offline CyanPrime
« Reply #17 - Posted 2011-05-15 04:17:56 »

Okay, so I'm now using the non-blocking DatagramChannel, and the code for this problem isn't that big.  See, the clients seem to be connecting to the server in that the server incrementing the playerNum, but both clients both say their playerNum is 0, so it seems like the clients aren't getting the data. Any idea why?

Server:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;


public class TestServer {
   DatagramChannel channel;
   SocketAddress player1IP;
   static int[] playerX;
   int enemy[];
   
   public void doStuff(){
      int playerNum = 0;
       playerX = new int[2];
       playerX[0] = 50;
       playerX[1] = 200;
       enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
       
      channel = null;
      try {
         channel = DatagramChannel.open();
      } catch (IOException e3) {
         e3.printStackTrace();
      }
       SocketAddress address = new InetSocketAddress(4444);
       DatagramSocket socket = channel.socket();
       try {
         socket.bind(address);
      } catch (SocketException e3) {
         e3.printStackTrace();
      }
      ByteBuffer buffer = ByteBuffer.allocate(255);
     
        while(playerNum < 2){
           SocketAddress client = null;
         try {
            client = channel.receive(buffer);
         } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
         }
           
         if(!client.equals(player1IP)){
               if(playerNum == 0){
                  player1IP = client;
               }
           
         
               ByteBuffer sendBuf = ByteBuffer.allocate(255);
              System.out.println("#:"+playerNum);
              sendBuf.putInt(playerNum);
              try {
               channel.send(sendBuf, client);
            } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
            }
             
              System.out.println("Connected with player: " + playerNum + " Now incrementing" + "\n");
              playerNum++;
              System.out.println("Incremented to: " + playerNum+ "\n");
         }
        }
       
        while(true){
           serverLoop();
        }
   }
   
   public void serverLoop(){}
   
   public static void main(String[] args){
      TestServer t = new TestServer();
      t.doStuff();
   }
}


Client:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;


import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

public class TestClient extends BasicGame{
   int playerNum = 0;
   int[] playerX;
   int[] enemy;
   
   DatagramChannel channel;
   
   public  TestClient()
    {
        super("Test Client");
    }
   
   public static void main(String[] args)
   throws SlickException
   {
       AppGameContainer app =
         new AppGameContainer(new TestClient());
     
       app.setDisplayMode(640, 480, false);
       app.setTargetFrameRate(60);
       app.setAlwaysRender(true);
       app.start();
   }

   @Override
   public void render(GameContainer gc, Graphics g) throws SlickException {
      g.fillRect(playerX[0], 0, 50, 50);
      g.fillRect(playerX[1], 0, 50, 50);
      g.drawString("px:" + playerX[playerNum], 10, 10);
      g.drawString("ex:" + playerX[enemy[playerNum]], 10, 25);
      g.drawString("p#:" + playerNum, 10, 40);
   }

   @Override
   public void init(GameContainer gc) throws SlickException {
      playerX = new int[2];
      playerX[0] = 0;
      playerX[1] = 0;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
      enemy = new int[2];
      enemy[0] = 1;
      enemy[1] = 0;
     
      try{
         channel = DatagramChannel.open();
          SocketAddress address = new InetSocketAddress(0);
          DatagramSocket socket = channel.socket();
          socket.bind(address);
         
          SocketAddress server = new InetSocketAddress("76.121.76.188", 4444);
          channel.connect(server);
         
          ByteBuffer sendBuf = ByteBuffer.allocate(255);
          sendBuf.put((byte) 0);
          channel.send(sendBuf, server);
         
          ByteBuffer receiveBuf  = ByteBuffer.allocate(255);
          channel.receive(receiveBuf);
         this.playerNum  = receiveBuf.getInt();
         System.out.println("#:"+this.playerNum);
         
         
      }
     
      catch(Exception e){
         e.printStackTrace();
      }
   }

   @Override
   public void update(GameContainer gc, int delta) throws SlickException {
      Input input = gc.getInput();
       if(input.isKeyDown(Input.KEY_A))
           {
               playerX[playerNum]-=2;
           }
   
           if(input.isKeyDown(Input.KEY_D))
           {
              playerX[playerNum]+=2;
           }
   }
}
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #18 - Posted 2011-05-16 00:01:13 »

What is your exact output on the console from your TestServer and TestClient instances?

Offline CyanPrime
« Reply #19 - Posted 2011-05-16 00:21:49 »

Client: (both)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
Sun May 15 17:20:43 PDT 2011 INFO:Slick Build #229
Sun May 15 17:20:43 PDT 2011 INFO:LWJGL Version: 2.6
Sun May 15 17:20:43 PDT 2011 INFO:OriginalDisplayMode: 1024 x 600 x 32 @60Hz
Sun May 15 17:20:43 PDT 2011 INFO:TargetDisplayMode: 640 x 480 x 0 @0Hz
Sun May 15 17:20:44 PDT 2011 INFO:Starting display 640x480
Sun May 15 17:20:44 PDT 2011 INFO:Use Java PNG Loader = true
WARNING: Found unknown Windows version: Windows 7
Attempting to use default windows plug-in.
Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
Sun May 15 17:20:44 PDT 2011 INFO:Found 0 controllers
#:0


Server:
1  
2  
3  
4  
5  
6  
7  
8  
9  
#:0
Connected with player: 0 Now incrementing

Incremented to: 1

#:1
Connected with player: 1 Now incrementing

Incremented to: 2
Offline CyanPrime
« Reply #20 - Posted 2011-05-16 03:18:51 »

I keep trying, lol. Now the client and server channels are unblocking, and I['ve got a few calls in while loops now. also I'm sending 2 instead of playerNum from the server for testing. Client still says it gets 0, even when not null?

Server:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
 
 
public class TestServer {
    DatagramChannel channel;
    SocketAddress player1IP;
    static int[] playerX;
    int enemy[];
     
    public void doStuff(){
        int playerNum = 0;
        playerX = new int[2];
        playerX[0] = 50;
        playerX[1] = 200;
        enemy = new int[2];
        enemy[0] = 1;
        enemy[1] = 0;
         
        channel = null;
        try {
            channel = DatagramChannel.open();
        } catch (IOException e3) {
            e3.printStackTrace();
        }
        SocketAddress address = new InetSocketAddress(4444);
        DatagramSocket socket = channel.socket();
        try {
            socket.bind(address);
        } catch (SocketException e3) {
            e3.printStackTrace();
        }
       
        try {
         channel.configureBlocking(false);
      } catch (IOException e2) {
         // TODO Auto-generated catch block
         e2.printStackTrace();
      }
       
        ByteBuffer buffer = ByteBuffer.allocate(255);
         
        while(playerNum < 2){
            SocketAddress client = null;
            try {
               while(client == null){
                  client = channel.receive(buffer);
               }
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
             
            if(!client.equals(player1IP)){
                if(playerNum == 0){
                    player1IP = client;
                }
             
             
                ByteBuffer sendBuf = ByteBuffer.allocate(255);
                System.out.println("#:"+playerNum);
                sendBuf.putInt(2);
                try {
                    channel.send(sendBuf, client);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                 
                System.out.println("Connected with player: " + playerNum + " Now incrementing" + "\n");
                playerNum++;
                System.out.println("Incremented to: " + playerNum+ "\n");
            }
        }
         
        while(true){
            serverLoop();
        }
    }
     
    public void serverLoop(){}
     
    public static void main(String[] args){
        TestServer t = new TestServer();
        t.doStuff();
    }
}


Client
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
 
 
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
 
public class TestClient extends BasicGame{
    int playerNum = 0;
    int[] playerX;
    int[] enemy;
     
    DatagramChannel channel;
     
    public  TestClient()
    {
        super("Test Client");
    }
     
    public static void main(String[] args)
    throws SlickException
    {
         AppGameContainer app =
            new AppGameContainer(new TestClient());
         
         app.setDisplayMode(640, 480, false);
         app.setTargetFrameRate(60);
         app.setAlwaysRender(true);
         app.start();
    }
 
    @Override
    public void render(GameContainer gc, Graphics g) throws SlickException {
        g.drawString("px:" + playerX[playerNum], 10, 10);
        g.drawString("ex:" + playerX[enemy[playerNum]], 10, 25);
        g.drawString("p#:" + playerNum, 10, 40);
    }
 
    @Override
    public void init(GameContainer gc) throws SlickException {
        playerX = new int[2];
        playerX[0] = 0;
        playerX[1] = 0;
        enemy = new int[2];
        enemy[0] = 1;
        enemy[1] = 0;
        enemy = new int[2];
        enemy[0] = 1;
        enemy[1] = 0;
         
        try{
            channel = DatagramChannel.open();
            SocketAddress address = new InetSocketAddress(0);
            DatagramSocket socket = channel.socket();
            socket.bind(address);
             
            SocketAddress server = new InetSocketAddress("76.121.76.188", 4444);
            channel.connect(server);
           
            channel.configureBlocking(false);
             
            ByteBuffer sendBuf = ByteBuffer.allocate(255);
            sendBuf.put((byte) 0);
            channel.send(sendBuf, server);
             
            ByteBuffer receiveBuf  = ByteBuffer.allocate(255);
            while(channel.receive(receiveBuf) == null);
            this.playerNum  = receiveBuf.getInt();
            System.out.println("#:"+this.playerNum);
             
             
        }
         
        catch(Exception e){
            e.printStackTrace();
        }
    }
 
    @Override
    public void update(GameContainer gc, int delta) throws SlickException {
        Input input = gc.getInput();
         if(input.isKeyDown(Input.KEY_A))
            {
                playerX[playerNum]-=2;
            }
     
            if(input.isKeyDown(Input.KEY_D))
            {
                playerX[playerNum]+=2;
            }
    }
}
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #21 - Posted 2011-05-16 03:40:17 »

Ok multiple things:
1. don't forget to set the SocketAdress client variable in TestServer to null so you can enter that while loop again.
2. Because this a non-blocking channel, calling receive() in TestClient doesn't guarantee that data will be available, so you've got to put it another while loop:
1  
2  
3  
while(channel.receive(receiveBuff) == null) {
    Thread.yield();
}

Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #22 - Posted 2011-05-16 04:01:07 »

So all fixed?

Offline CyanPrime
« Reply #23 - Posted 2011-05-16 14:21:46 »

Yeah. You have to .flip() your bytebuffer before sending and after receiving it. lol
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #24 - Posted 2011-05-16 17:02:21 »

Yeah. You have to .flip() your bytebuffer before sending and after receiving it. lol
Cool, glad to see you got it working. Sorry I wasn't able to look at it until you already had it done. Smiley

See my work:
OTC Software
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #25 - Posted 2011-05-16 23:20:51 »

Yeah. You have to .flip() your bytebuffer before sending and after receiving it. lol
Cool, glad to see you got it working. Sorry I wasn't able to look at it until you already had it done. Smiley
Hey how come he gets a medal Angry
(jk Tongue )

But that's just weird, why call "flip()" when you receive it? O.o

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #26 - Posted 2011-05-19 04:09:43 »

The reason Java is named as such is because Games Josling, who invented Java, used to live in the country of Java where he DID NOT drink coffee, he had hot chocolate. It's a common misunderstanding that it's based off coffee, the logo for Java is actually the shape of the country, NOT a coffee cup. And the steam rising is the vapors rising from the dense population of the country.

See my work:
OTC Software
Offline ra4king

JGO Kernel


Medals: 355
Projects: 3
Exp: 5 years


I'm the King!


« Reply #27 - Posted 2011-05-19 10:33:39 »

Ah thanks for for you help. However, it would make more sense if the receive() method did that since it is just doing "put(byte)" length number of times.

Offline Icecore

Senior Devvie


Medals: 5



« Reply #28 - Posted 2011-05-19 20:08:53 »

Here how data sends in theory .You send :
Data 1
Data 2
Data 3
Client receive:
Data 1
Data 2
Data 3
But on practice data may be lost or will be received in not right order (lags in network)
If you want filter data manually you can add to send Data : time of sending , packet number ,
Or any else information that you need Wink
I don’t have many experience in Socket programming (only program http sending and some multi thread TCP client-server;))
Offline jeffpk

Senior Newbie


Medals: 2



« Reply #29 - Posted 2011-05-24 22:47:13 »

Yeah. You have to .flip() your bytebuffer before sending and after receiving it. lol
Cool, glad to see you got it working. Sorry I wasn't able to look at it until you already had it done. Smiley
Hey how come he gets a medal Angry
(jk Tongue )

But that's just weird, why call "flip()" when you receive it? O.o

You need to copy data out in the reverse order it was sent. You can think of it sort of like this:

Actually that is totally wrong.

On a reliable connection packets arriove in the order they were sent. In a non-reliable, they arrive in any order.

But within the packet you need to read the data out in the same order you wrote it in.  If you actually RTFM you find out that flip doesnt do what you think it does.
Quote
Flips this buffer. The limit is set to the current position and then the position is set to zero. If the mark is defined then it is discarded.

When you finish writing into the buffer, you are in "just written" state.  Your current position is the byte just after the last one you wrote (the next place to write if you continued writing) and your limit is the last byte in the buffer.

Flip puts you into "ready to read state" by putting the current position into the limit so you cannot read past what you wrote, and then putting 0 into current position as this is the place you want to start reading from.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

PocketCrafter7 (12 views)
2014-11-28 16:25:35

PocketCrafter7 (8 views)
2014-11-28 16:25:09

PocketCrafter7 (9 views)
2014-11-28 16:24:29

toopeicgaming1999 (76 views)
2014-11-26 15:22:04

toopeicgaming1999 (66 views)
2014-11-26 15:20:36

toopeicgaming1999 (15 views)
2014-11-26 15:20:08

SHC (29 views)
2014-11-25 12:00:59

SHC (27 views)
2014-11-25 11:53:45

Norakomi (32 views)
2014-11-25 11:26:43

Gibbo3771 (28 views)
2014-11-24 19:59:16
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!