Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (762)
Games in Android Showcase (229)
games submitted by our members
Games in WIP (846)
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  
  Server/Client  (Read 2152 times)
0 Members and 1 Guest are viewing this topic.
Offline zFollette

Junior Devvie


Exp: 2 years


I like jokes


« Posted 2014-02-04 03:45:22 »

So, pleased with me advancement in 3D, I took it upon myself to try some Server/Client communications. I have server/client experience (very little), so this was kind of expected. Basically, my client lags. I have not gotten to large scale test this yet, so right now, that is the only problem. I can show you a video (which I took from an Iphone because I cba to mix video from 2 computers). The silver computer is the computer with the server and the client running, and the black computer is just the client. The block dot is the player.

Video: http://s1375.photobucket.com/user/zFollette/media/IMG_1142_zps903e8b07.mp4.html

Here is some code:

Client class (in the game)
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  
public class Client {

    private Socket socket;
    private final String ip = "192.168.0.8";
    String local;
    private final int port = 43595;
    private BufferedReader br;
    private PrintWriter pw;
    public static final ArrayList<Player> players = new ArrayList<>();

    public Client() throws IOException {
        handleConnection();
    }

    private void handleConnection() throws IOException {
        socket = new Socket();
        socket.connect(new InetSocketAddress(ip, port));
        local = socket.getInetAddress().getHostAddress();
        br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        pw = new PrintWriter(socket.getOutputStream());
        Thread t = new Thread(new Connection());
        t.start();
    }

    public void sendMessage(String message) {
        pw.println(message);
        pw.flush();
    }

    private class Connection implements Runnable {

        @Override
        public void run() {
            String line;

            try {
                while ((line = br.readLine()) != null) {
                    String ip = line.split(": P")[0].trim();
                    if (line.contains("POSITION")) {
                        String[] values = line.replaceAll(ip, "").replaceAll(": POSITION:", "").trim().split(", ");

                        Player p = new Player(ip);
                        p.setX(Float.parseFloat(values[0]));
                        p.setY(Float.parseFloat(values[1]));
                        p.setZ(Float.parseFloat(values[2]));

                        if (!contains(players, ip) && !ip.equals(local)) {
                            players.add(p);
                        }

                        for (int i = 0; i < players.size(); i++) {
                            if (players.get(i).getIp().equals(ip)) {
                                players.set(i, p);
                                break;
                            }
                        }
                    }
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        private boolean contains(ArrayList<Player> s, String s1) {
            for (int i = 0; i < s.size(); i++) {
                if (s.get(i).getIp().equals(s1)) {
                    return true;
                }
            }
            return false;
        }
    }
}


Server class (seperate program)
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  
public final class Server {

    private ServerSocket server;
    private Socket socket;
    private final int port = 43595;
    private final String ip = "192.168.0.8";
    public static ArrayList<Player> players = new ArrayList<>();

    public Server() throws IOException {
        handleConnection();
    }
   
    private void handleConnection() throws IOException {
        server = new ServerSocket();
        server.bind(new InetSocketAddress(ip, port));

        while (true) {
            socket = server.accept();
            Player player = new Player(socket.getInetAddress().getHostAddress());
            player.setS(socket);
            players.add(player);
            Thread t = new Thread(new ConnectionHandler(socket, player));
            t.start();
        }
    }
}


ConnectionHandler class (part of 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  
public class ConnectionHandler implements Runnable {

    Socket s;
    int port = 43595;
    Player p;

    public ConnectionHandler(Socket s, Player p) {
        this.s = s;
        this.p = p;
    }

    @Override
    public void run() {
        try {
            System.out.println("Client: " + s.getInetAddress() + " has connected.");
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            PrintWriter pw;
            String line;

            while (true) {
                while ((line = br.readLine()) != null) {
                    if (line.startsWith("POSITION:")) {
                        String[] values = line.replaceAll("POSITION:", "").trim().split(", ");
                        p.setX(Float.parseFloat(values[0]));
                        p.setY(Float.parseFloat(values[1]));
                        p.setZ(Float.parseFloat(values[2]));
                       
                        ArrayList<Player> ps = Server.players;
                       
                        for (int i = 0; i < ps.size(); i++) {
                            Player p1 = ps.get(i);
                            for (int j = 0; j < ps.size(); j++) {
                                    pw = new PrintWriter(ps.get(j).getS().getOutputStream());
                                    pw.println(p1.getIp() + ": POSITION: " + p1.getX() + ", " + p1.getY() + ", " + p1.getZ());
                                    pw.flush();
                            }
                        }
                    }
                }
            }

        } catch (IOException ex) {
            System.out.println("Client: " + s.getInetAddress() + " has disconnected.");
        }
    }
}


So, I am going to assume my code is a terrible way of doing what I want, because it usually is, lol. But I also have another question. The computer that is lagging is slightly less powerful (intel i5, intel graphics 3000) than the one that is not lagging (intel i7, NVIDIA optimus). Could this be the problem? I ruled it out earlier because the rest of the game (cubes and what not) render fine. Its the the dot.

EDIT: Possible cause, I render the dot in immediate mode.

Humor will keep you alive.
Offline DrZoidberg

JGO Coder


Medals: 21



« Reply #1 - Posted 2014-02-04 08:15:25 »

I don't see a call to repaint in your code.
There are a few things you could try.
Use DataInput/OutputStream and don't buffer the streams.
Call Socket.setTcpNoDelay(true); and Socket.setTrafficClass(0x10); before you connect the socket. i.e. between line 16 and 17 in your code.
Offline zFollette

Junior Devvie


Exp: 2 years


I like jokes


« Reply #2 - Posted 2014-02-04 13:36:40 »

I don't see a call to repaint in your code.
There are a few things you could try.
Use DataInput/OutputStream and don't buffer the streams.
Call Socket.setTcpNoDelay(true); and Socket.setTrafficClass(0x10); before you connect the socket. i.e. between line 16 and 17 in your code.

Well, I guess it is worthy to mention that this is openGL, not swing. However, I will look at your other suggestions.

EDIT: I have no time to test, but the documentation looks promising...

Humor will keep you alive.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline kalkitus

Junior Devvie


Medals: 2
Exp: 6 years



« Reply #3 - Posted 2014-02-04 13:59:18 »

Are you doing any kind of client side prediction? Essentially, you don't want to wait for the server to confirm your movements.

Gabriel's series of articles is pretty helpful. This is probably exactly what you want http://gabrielgambetta.com/fpm_live.html
Offline zFollette

Junior Devvie


Exp: 2 years


I like jokes


« Reply #4 - Posted 2014-02-05 00:43:08 »

Are you doing any kind of client side prediction? Essentially, you don't want to wait for the server to confirm your movements.

Gabriel's series of articles is pretty helpful. This is probably exactly what you want http://gabrielgambetta.com/fpm_live.html


That looks like exactly what I need.

EDIT: I read through it, but I don't understand how I could effectivly predict the positions of a player, in they game (like most others) I can move up, down, left,right, forward, backward, and anywhere in between. There is no limit to where I can move, therefor making the game un-predictable

Humor will keep you alive.
Offline jonjava
« Reply #5 - Posted 2014-02-05 01:53:25 »

No. Read it again. Ask help on specific things.

Offline zFollette

Junior Devvie


Exp: 2 years


I like jokes


« Reply #6 - Posted 2014-02-05 03:51:22 »

No. Read it again. Ask help on specific things.

Ok, how can I predict the next movement if the amount of movements to select from is (for all intents and purposes) unlimited.

Humor will keep you alive.
Offline Dxu1994
« Reply #7 - Posted 2014-02-05 04:18:34 »

1.

Don't use strings to encode your packet data. Use binary.

You can either choose to prefix each packet with a header (with length and packet id) or use just packet id and fixed length packets, or a mix of both. For example, movement packets should always be the same size, { InputID, Timestamp } but attack packets may be different sized, depending on your game for example.

2.

Do client side prediction, for the local player and for remote players. Do interpolation for remote players to make their movement smooth, and just implement the same movement algorithm on the client as you have on the server, so basically the client moves, server gets an update, moves him, sends the packet back to client, if this movement is old, just discard it otherwise update your local player to server position.

3.

You may need to do lag compensation if you are making a FPS for example. Shooting packets should be sent with the Timestamp and the server can recalculate exactly where the entities were at that timestamp, and apply the shot.

Offline jonjava
« Reply #8 - Posted 2014-02-05 12:16:37 »

No. Read it again. Ask help on specific things.

Ok, how can I predict the next movement if the amount of movements to select from is (for all intents and purposes) unlimited.

Add them all up. http://www.youtube.com/watch?v=xp6ibuI8UuQ

Pages: [1]
  ignore  |  Print  
 
 

 
EgonOlsen (353 views)
2018-06-10 19:43:48

EgonOlsen (354 views)
2018-06-10 19:43:44

EgonOlsen (294 views)
2018-06-10 19:43:20

DesertCoockie (528 views)
2018-05-13 18:23:11

nelsongames (844 views)
2018-04-24 18:15:36

nelsongames (832 views)
2018-04-24 18:14:32

ivj94 (1264 views)
2018-03-24 14:47:39

ivj94 (396 views)
2018-03-24 14:46:31

ivj94 (1067 views)
2018-03-24 14:43:53

Solater (414 views)
2018-03-17 05:04:08
Java Gaming Resources
by philfrei
2017-12-05 19:38:37

Java Gaming Resources
by philfrei
2017-12-05 19:37:39

Java Gaming Resources
by philfrei
2017-12-05 19:36:10

Java Gaming Resources
by philfrei
2017-12-05 19:33:10

List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05
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!