Reputation: 115
Ok, I am quite new to network programming and I am trying to solve this problem:
I have GUI based Java SE game for max 7 players and I want it to support multiplayer over the Internet.
Every instance of game would have its own client sending and receiving string.
And here comes the problem I cannot sufficiently solve. I need server and its only functionality is keeping client's sockets opened and on receiving some string just forward it to other clients. My first idea was to run server on the first player's machine and other players can connect to that server via its IP from outside. Now I discovered that getting public interface IP is not that easy as I thought so I searched and found the code written below to get some IP's that SHOULD be available from outside. When I try this at localhost, resulted IP is always some IPv6 + port and connecting from client using this credentials is successful and it works. When I start the server on another machine and copy these credentials for connecting from another computer it fails (it either doesn't connect or if it does and client sends message, server doesn't receive any).
So my next idea was to use some public IP on remote hosting server. So there would be some server running 24/7 (or if I programmatically from game tell him so) and I use its IP to unite all clients. I just don't know how to make this thing working and what technologies use.
I hope I explained my problem clearly and thanks for any ideas or even solutions :)
Get machine's public interface IP (where server is running) and prints that out code:
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface iface = interfaces.nextElement();
if (iface.isLoopback() || !iface.isUp()) { //127.xxx loopback
continue;
}
Enumeration<InetAddress> addresses = iface.getInetAddresses();
while (addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
String tmp = addr.getHostAddress();
if (tmp.startsWith("192.168.") //local IP
|| tmp.startsWith("10.") //local IP
|| tmp.startsWith("172.16.") //local IP
|| tmp.startsWith("172.31.") //local IP
|| tmp.startsWith("169.254") //single network IP
|| tmp.equals("255.255.255.255")) { //broadcast address
continue;
}
//cut "%net9","%wlan" etc stuff off
IP = tmp.substring(0, Math.max(0, tmp.indexOf('%')));
port=server.getPort();
System.out.println(IP + " " + port);
}
}
Upvotes: 1
Views: 2049
Reputation: 1289
if running on a "local network" then having a serversocket is fine, but we deal with NAT and the internet which means that 98% of machines are not directly internet visible. (i.e. opening a TCP port for listening on the machine will not result in the machines Internet IP address having that port be listened to. )
The initial option would be to have a server on public hosting which mediates communication between players and each players machine is responsible for maintaining 'game state' but then you run into the issue of synchronization. (e.g. one players machine thinks that they have hit and killed another player prior to that machine receiving a command to tell it that the opponent has moved. )
The current method of thinking for this paticular problem is to have the server maintain the 'game state' (e.g. player positions, health, weapon damage, etc. )
having players send 'commands' to the server (e.g. move, fire, jump. ) and then having the server report to all players the 'minor' game state changes. (so Time becomes an important factor and all messages between clients and server need to be timestamped. )
so your clients maintain what they believe 'game state' to be, recieving updates from the server to 'correct' errors.
In addition to this every once in a while the server should send a dump of the entire 'game state' to each player as a 'sync' message to ensure what they believe to be the game state 'is' the actual game state.
If your language of choice was "C" it would be trivial to take the md5 checksum of the entire game state structure and then transmit this to players periodically and only performing a sync message..
The links below should give you a good starting point.
And the enclosing page with a little bit more detail
Upvotes: 1