• (2 Pages)
  • +
  • 1
  • 2

Creating a server to serve clients Rate Topic: ***** 5 Votes

#1 WolfCoder  Icon User is offline

  • Isn't a volcano just an angry hill?
  • member icon


Reputation: 790
  • View blog
  • Posts: 7,623
  • Joined: 05-May 05

Post icon  Posted 03 December 2007 - 11:48 AM

*
POPULAR

Update

Quote

I was going to write an MMORPG basics tutorial, but then I realized there shouldn't be a tutorial for it. If you can't piece together knowledge to make an MMORPG (as it incorporates lots of things) you aren't cut out to even think of making an MMORPG.


Preface:
Alright! I've figured out how to do this in an efficient way to where the clients can connect and begin transmission to the server program quickly. For all of those who want to try out making an MMORPG, this is actually an easy way to start. Before going through my tutorial, please learn the basics of JAVA or you might get lost (however, you can at least try it out anyway but realize you may become a little lost).


I bet you wanna make the kinds of MMO games she plays all the time right?
Posted Image

Or maybe you just wanna special server and client system for something in particular? Well in JAVA it's much easier than even I thought! Pull up a chair and fire up your programming environment~

There are two JAVA objects in the API that are interesting to us. The ServerSocket and the Socket object. One to accept socket connections from the client and the other to connect to the server. Does it sound too simple? It's is! In fact, you'll run into problems with synchronization way more often than connecting the clients. Let's connect a simple client to a simple server! Compile both programs and run them as two different instances of a program.

import java.net.ServerSocket;
import java.net.Socket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class ServerTest
{
	private static ServerSocket serverSocket;
	private static Socket clientSocket;
	private static BufferedReader bufferedReader;
	private static String inputLine;
	public static void main(String[] args)
	{
		// Wait for client to connect on 63400
		try
		{
			serverSocket = new ServerSocket(63400);
			clientSocket = serverSocket.accept();
			// Create a reader
			bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
			// Get the client message
			while((inputLine = bufferedReader.readLine()) != null)
			System.out.println(inputLine);
		}
		catch(IOException e)
		{
			System.out.println(e);
		}
	}
}



and the client...

import java.net.Socket;
import java.io.PrintWriter;
public class ClientTest
{
	private static Socket socket;
	private static PrintWriter printWriter;
	public static void main(String[] args)
	{
		try
		{
			socket = new Socket("localhost",63400);
			printWriter = new PrintWriter(socket.getOutputStream(),true);
			printWriter.println("Hello Socket");
			printWriter.println("EYYYYYAAAAAAAA!!!!");
		}
		catch(Exception e)
		{
			System.out.println(e);
		}
	}
}



Run the server... It looks like it's frozen but it's waiting for a socket from the client to connect. Run the client and it will finish. Take a look at the server program's console... There's your messages followed by an exception generated from the socket from the client disconnecting.

getInputStream() and getOutputStream() will hold the execution there until the client has established an output stream where the server establishes an input stream. Any sort of input or output stream can be created (like an ObjectInputStream). So you can send and receive data in any way you wish doing this. Whatever way is most comfortable to you (or the way you think is easiest to learn) is fine for now.

The parts of interest are the following lines:
socket = new Socket("localhost",63400);
serverSocket = new ServerSocket(63400);
To connect, the target is the local host on the same machine. It could be an IP address for a server if you want to connect over the internet. If you're on a LAN then you can try this on two separate machines. Use the IP of the machine running the server instead of "localhost" to try it out. Also, depending on your network structure, you may be able to do this over the internet with some other user.

But...
How do you connect multiple clients? I mean it is a server, it's got to serve multiple clients! What good is an MMORPG or a chat room with just you in there? You might want to have a loop accepting socket connections and save them in a list to track all the clients... But you'll encounter a problem! For sending, receiving, accepting, and connecting things, they all WAIT until the operation is complete! If you've got someone with a slow connection it will sit there and wait for them to complete the transaction or fail!

Think for a moment. You've got multiple people who want service and some are slower than others, but you gotta satisfy everyone. That is where you multitask! You need parallel operations for ALL clients. And... Thread will do just that for you!

Here's a cutout from my own server program.

import java.net.ServerSocket;
import java.net.Socket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.IOException;
import java.util.ArrayList;
/**
 * This handles all of the Umbra clients in the room.
 * It accepts new connections and adds them to the room.
 * It is a runnable thread and when the start method is called, it will accept clients.
 */
public class UmbraRoom extends Thread
{
	private static final int UMBRA_PORT = 30480;
	private static final int ROOM_THROTTLE = 200;
	private ServerSocket serverSocket;
	private InetAddress hostAddress;
	private Socket socket;
	private ArrayList<UmbraUser> users = new ArrayList<UmbraUser>();
	/**
	 * Creates a new Umbra room for clients to connect to.
	 */
	public UmbraRoom()
	{
		// Attempt to get the host address
		try
		{
			hostAddress = InetAddress.getLocalHost();
		}
		catch(UnknownHostException e)
		{
			System.out.println("Could not get the host address.");
			return;
		}
		// Announce the host address
		System.out.println("Server host address is: "+hostAddress);
		// Attempt to create server socket
		try
		{
			serverSocket = new ServerSocket(UMBRA_PORT,0,hostAddress);
		}
		catch(IOException e)
		{
			System.out.println("Could not open server socket.");
			return;
		}
		// Announce the socket creation
		System.out.println("Socket "+serverSocket+" created.");
	}
	/**
	 * Starts the client accepting process.
	 */
	public void run()
	{
		// Announce the starting of the process
		System.out.println("Room has been started.");
		// Enter the main loop
		while(true)
		{
			// Remove all disconnected clients
			for(int i = 0;i < users.size();i++)
			{
				// Check connection, remove on dead
				if(!users.get(i).isConnected())
				{
					System.out.println(users.get(i)+" removed due to lack of connection.");
					users.remove(i);
				}
			}
			// Get a client trying to connect
			try
			{
				socket = serverSocket.accept();
			}
			catch(IOException e)
			{
				System.out.println("Could not get a client.");
			}
			// Client has connected
			System.out.println("Client "+socket+" has connected.");
			// Add user to list
			users.add(new UmbraUser(socket));
			// Sleep
			try
			{
				Thread.sleep(ROOM_THROTTLE);
			}
			catch(InterruptedException e)
			{
				System.out.println("Room has been interrupted.");
			}
		}
	}
}



import java.net.Socket;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
 * This object handles the execution for a single user.
 */
public class UmbraUser
{
	private static final int USER_THROTTLE = 200;
	private Socket socket;
	private boolean connected;
	private Inport inport;
	/**
	 * Handles all incoming data from this user.
	 */
	private class Inport extends Thread
	{
		private ObjectInputStream in;
		public void run()
		{
			// Open the InputStream
			try
			{
				in = new ObjectInputStream(socket.getInputStream());
			}
			catch(IOException e)
			{
				System.out.println("Could not get input stream from "+toString());
				return;
			}
			// Announce
			System.out.println(socket+" has connected input.");
			// Enter process loop
			while(true)
			{
				// Sleep
				try
				{
					Thread.sleep(USER_THROTTLE);
				}
				catch(Exception e)
				{
					System.out.println(toString()+" has input interrupted.");
				}
			}
		}
	}
	/**
	 * Creates a new Umbra Client User with the socket from the newly connected client.
	 *
	 * @param newSocket  The socket from the connected client.
	 */
	public UmbraUser(Socket newSocket)
	{
		// Set properties
		socket = newSocket;
		connected = true;
		// Get input
		inport = new Inport();
		inport.start();
	}
	/**
	 * Gets the connection status of this user.
	 *
	 * @return  If this user is still connected.
	 */
	public boolean isConnected()
	{
		return connected;
	}
	/**
	 * Purges this user from connection.
	 */
	public void purge()
	{
		// Close everything
		try
		{
			connected = false;
			socket.close();
		}
		catch(IOException e)
		{
			System.out.println("Could not purge "+socket+".");
		}
	}
	/**
	 * Returns the String representation of this user.
	 *
	 * @return  A string representation.
	 */
	public String toString()
	{
		return new String(socket.toString());
	}
}



This will accept Socket connections from a client. It also tries to establish an InputStream with the client. Look closely, notice how I start some threads for every client. The rest of the clients won't be effected when a different client is slow, it won't wait for it. Study carefully on how dead clients are closed and removed and how the threads quit on failure. Now, I purposefully left the threads to run even when the client is removed, but you can see where the connection can fail and where you should make the thread quit (using return is easy).

Lots of exceptions can occur for various reasons, it's important to do what is needed in their case. Try writing a client to connect to this server and connect lots of them. Then make the server remove them when they disconnect.

From here on out, I shouldn't tell you how to establish a stream pair going the other way (from server to client) or what the server and client should do to messages being received. This is because... It varies from what you need! Right in the thread process where you see the InputStream, you can read objects and act upon them, or with the OutputStream you can send objects. It's all up to you now, just be sure to use Threads or your program will sit there and wait, which isn't what you want!

OK, OK, you're losing your attention because you really want to make an MMORPG right?
Posted Image
You can't hide it from me! I'll make a Tutorial for that later when I have time so stick around. I'll get a little deeper in making a networked game with a server (which doesn't really need a and a client (which uses a video panel and everything).

While you wait, I suggest you practice just making the server echo Strings from the client and to periodically send Strings back to the client. If you can do this for multiple clients without errors or having the client or server freeze up and wait, then you're all set for my next tutorial :)/>

Some images from Lucky Star (Kyoto Animation)

Update

Quote

I was going to write an MMORPG basics tutorial, but then I realized there shouldn't be a tutorial for it. If you can't piece together knowledge to make an MMORPG (as it incorporates lots of things) you aren't cut out to even think of making an MMORPG.

This post has been edited by WolfCoder: 18 February 2014 - 04:03 PM


Is This A Good Question/Topic? 13
  • +

Replies To: Creating a server to serve clients

#2 m78  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 10-February 08

Posted 10 February 2008 - 01:08 PM

Is this how I get multi-ple client on a netowrk to use the same application?
For example, I have to write a text-adventure game and such game is supposed to be played on the Internet by multiple users simultaneosly.

How do I go about that?
Was This Post Helpful? 0
  • +
  • -

#3 ever388  Icon User is offline

  • New D.I.C Head

Reputation: -11
  • View blog
  • Posts: 1
  • Joined: 02-May 08

Posted 02 May 2008 - 02:49 PM

i think u and me could make the best game ever you no how to do it all and i hav played every adventure game there is


P.S please reply to me at pooman132132@hotmail.com

This post has been edited by ever388: 02 May 2008 - 03:27 PM

Was This Post Helpful? -11
  • +
  • -

#4 Rickster0  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 16
  • View blog
  • Posts: 236
  • Joined: 08-July 08

Posted 10 July 2008 - 03:32 AM

This tutorial is BLOODY AWSOME. YAY WolfCoder

:D
Was This Post Helpful? 0
  • +
  • -

#5 ~Zack  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 08-May 09

Posted 08 May 2009 - 02:48 PM

Did you ever make the MMORPG version of this tutorial?
and very nice learned some stuff.
Was This Post Helpful? 0
  • +
  • -

#6 WolfCoder  Icon User is offline

  • Isn't a volcano just an angry hill?
  • member icon


Reputation: 790
  • View blog
  • Posts: 7,623
  • Joined: 05-May 05

Posted 09 September 2009 - 08:54 PM

I was going to write an MMORPG basics tutorial, but then I realized there shouldn't be a tutorial for it. If you can't piece together knowledge to make an MMORPG (as it incorporates lots of things) you aren't cut out to even think of making an MMORPG.
Was This Post Helpful? 2
  • +
  • -

#7 Metropoler  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 78
  • Joined: 29-December 09

Posted 04 January 2010 - 01:54 PM

This tutorial is amazing! I've only found tutorials about a simple socket connection with one client. This multi-threading is superb! Thanks a lot
Was This Post Helpful? 0
  • +
  • -

#8 chaoge  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 07-December 09

Posted 19 January 2010 - 04:12 AM

nice "tutorial" huh!! thakz so much!!! :^:
Was This Post Helpful? 0
  • +
  • -

#9 Keerigan  Icon User is offline

  • D.I.C Head

Reputation: 10
  • View blog
  • Posts: 55
  • Joined: 04-February 10

Posted 04 February 2010 - 01:07 PM

Let me start by saying that this is a very nice tutorial!

But every time I connect to the server in the second example, it says that it can't get the input stream from the thread.

I am using the same client code as from the first part of your tutorial, do I have to do something differently?
Was This Post Helpful? 0
  • +
  • -

#10 v0rtex  Icon User is offline

  • Caffeine: db "Never Enough!"
  • member icon

Reputation: 223
  • View blog
  • Posts: 773
  • Joined: 02-June 10

Posted 03 May 2011 - 06:52 AM

Awesome tutorial, helped a lot. Thanks! :)
Was This Post Helpful? 0
  • +
  • -

#11 robinthapa  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 32
  • Joined: 16-June 11

Posted 16 June 2011 - 10:21 PM

Quote

What if the messages exchanged between the clients and servers where to be dumped in a text file.
How to procceed in the tutorials

Was This Post Helpful? 0
  • +
  • -

#12 charpede  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 24
  • Joined: 18-October 11

Posted 21 October 2011 - 10:08 PM

This was an awesome tutorial. It really gets all the parts out there in terms of what's needed for the basics of networks.

Just a question though, do you not need to close the sendSocket on the server or the client side? I saw the try catch that might catch the interruption in connection but what happens when no users are left?

I might add a boolean statement in that is true while the loop should be running and then go false when no one is connected and have that false statement make it so that you run a sendSocket.close().

Is this even needed though? I'm still learning from the tutorials, so it's more of a point of clarification than a correction.
Thanks for posting this!
Was This Post Helpful? 0
  • +
  • -

#13 zauii  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 35
  • Joined: 02-January 11

Posted 18 December 2011 - 09:34 PM

How come that only the first message is sent if you try it over the internet?
The server only seems to revive the first client-message, whilst on local it prints all messages.
Was This Post Helpful? 0
  • +
  • -

#14 ninaBird  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 12-July 12

Posted 12 July 2012 - 03:39 PM

Hello,

Ok everyone please don't laugh. I am still a student and I am definitely much more proficient in coding c++ than Java. Anyways, I landed an internship, and my boss has me doing something I have never even fathomed before. I am to do 2 way SSL. I have gone online to look at examples. I did see WolfCoders example, and was able to implement that. But how am I to get this to work with SSL? I see from his example I am just making a connection. My main concern is the Server Side as I need to implement this for testing our Client side applications. I am using eclipse and have never generated any Certificates, nor am I in any way sure how to set my Server with this certificate, and how to give my server it's "bank" of accepted CA's. To make things simple, I am just going to set the Client side with a Certificate I have generated. Can somebody suggest any way in which to start. I am so lost. I appreciate any help.

Thanks

Nina
Was This Post Helpful? 0
  • +
  • -

#15 WolfCoder  Icon User is offline

  • Isn't a volcano just an angry hill?
  • member icon


Reputation: 790
  • View blog
  • Posts: 7,623
  • Joined: 05-May 05

Posted 18 February 2014 - 04:05 PM

There's something called an SSLSocketsFactory or something. It will create SSL sockets, automatically performing the initiation for you. Then you send and receive data normally.

You will need to read up on how to manage your keys and certificates in JAVA.
Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2