How to make a Multiplayer Applet game using UDP
Assuming you have the JDK installed and an IDE working where you can compile and run programs, we will get into the aspects of network coding.
We will be working with a server/client method using UDP, not TCP/IP. UDP is best for fast paced games that need up to date info, but can
handle lost packets every once in a while. We will be using an Applet for the client, but you can use a regular application for your game.
I will also be using a transfer method which utilizes the best defense against hackers, where the client only sends key presses vs. sending
other important information like where the player is currently located.
First of all you will want to download the UDPServer.java and
UDPClient.java source code to look at while reading this tutorial. For
easier use I put all the class files related to each side in one file. So just paste the code in one java file for simple compiling and testing.
The Structure
| The class structure of the Server is: |
The class structure of the Client is: |
- Game Class - Thread
- ServerThread Class - Thread
- Translator Class - Thread
- PlayerList Class - Helper
- Player Class - Storage
|
- UDPClient Class - Applet Thread
- ReceiveThread Class - Thread
- PlayerList Class - Helper
- Player Class - Storage
|
The Server Side
Lets take a look at the server code first. The server will house all the game's code, like the regular game loop and any other game related
code. The ServerThread class runs along side the regular game loop, it receives all the packets sent from clients.
protected DatagramSocket socket = null;
protected DatagramPacket packet = null;
We will start with the variables. DatagramSocket is the tunnel where all the packets are sent and received
through, and the DatagramPacket is the package that gets transferred in byte format.
socket = new DatagramSocket(5556);
This creates the socket on port 5556, you can use any unsigned 16 bit number in the range of 1024 to 65535 as
your port. Many of the ports below 1024 are reserved service ports used by other programs on your computer like e-mail.
public void receivePacket() throws IOException
{
//receive message from client
byte[] buf = new byte[256];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
//translate message in a thread
String message = new String(packet.getData(), 0, packet.getLength());
Translator translator = new Translator(playerList,message);
translator.start();
}
The receivePacket() method is one of the most important methods in the class. This will need the most
optimization since it will be receiving all the packets that all of the clients will be sending through out the
game. I have opted to put the translations of the packet strings in a seperate thread so the game loop can go on while the string is
translated into usable information.
packet = new DatagramPacket(buf, buf.length); creates a packet with the constructor taking a byte array and its
size for the packet. Be sure to keep the received packet size no bigger than this packet you specify or the received info will be truncated
into this packet's size.
The Translator translator = new Translator(playerList,message); line creates a temporary thread that will translate
the received message from the client. With the implementation I produced, all it does is retrieve wheather or not a key is pressed.
public void sendPacket() throws IOException
{
//create message of all xs and ys of all players
byte[] buf = playerList.toString().getBytes();
//send the message to the client to the given address and port
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
}
The sendPacket() method calls the playerList.toString() which converts all the
players positions for transport along with all the player's names for distinction. You can fill in all the data you would like all players
to know in the toString() method.
The next line retrieves the address from which the client sent the packet, and uses it as the destination address. The same thing happens
with the port. The next line packs all that information into the packet, then sends it over the socket used earlier.
The Client Side
The important thing to remember about the client is the socket does not need a port but the packet does need the address and port of
the server in which you are using. In this implementation the first thing the client does is retrieve the username and ip address through
the getParameter() method.
username = getParameter("username");
ipAddress = getParameter("ip");
These variables can be set in the html code that starts up the applet when using a browser with the following code.
<applet code="UDPClient.class" width="640" height="480">
<param name="username" value="Guest">
<param name="ip" value="localhost">
</applet>
Since we will be testing through our own IDE we will set username to Guest and the IP Adress to localhost.
socket = new DatagramSocket();
receiveThread = new ReceiveThread(socket,playerList);
receiveThread.start();
We then create a socket with no port as we stated above, and create a ReceiveThread passing the new
socket and the playerList as parameters to the constructor. The
receiveThread creates a thread that will receive repsonses from the server and translate them into player
x and y locations.
sendPacket();
The method above is the only important method that runs inside the client applet.
byte[] buf = getMessage().getBytes();
InetAddress address = InetAddress.getByName(ipAddress);
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 5556);
socket.send(packet);
Similar to the sending method of the server, the client instead creates an InetAddress from the given
ipAddress. The packet is then made from the address and the hardcoded port number
5556. The packet is then sent through the socket created earlier, with the message being the key presses.
The other method that is relevant to the network code is in the client receiving method which is running in the background waiting for any
messages sent back by the server. But after going through the code above, it should be self explanitory.
Running The Game
To test out the given code, you will be able to test it through your IDE as long as the ip address is localhost. To put it out on the internet
you will have to sign the client or run the server off where you host your website.
Running the server on your own computer for public use will require unlocking the port stated above in your firewall if no connections
are being made otherwise. You may also need to port forward the port number to your local network router.
I hope this helps anyone in their own endeavors, everyone is free to use this code in any way. Be sure to check out our games and help us
out by donating, we will always be an independent studio ;)
|
|
or |
|
Published June 15, 2009 - By Oscar J. Gomez
|