[TUT] Server && Client Program

Post all your tuts or request for tuts here.
Post Reply
Baseball435
Posts: 548
Joined: Sun May 30, 2010 3:49 am

[TUT] Server && Client Program

Post by Baseball435 »

Hey everyone, today I have been working on a simple server and client program where a client types something in, the server receives it, and then it sends it back to the client. After about a half an hour I finished it and decided to put a tutorial onto here. Yes it's not too useful but this is the basics of a chat client and can help you understand server and clients better. Also the source code with a virus scan will be at the bottom. Before I start I just want to say that if you don't like the way my code looks, please don't criticize. Everyone has their own way of organizing and setting up code so don't put comments saying your code doesn't appeal to me. Thanks a lot.

Lets get started!

Part 1

So for this there will be two separate projects, a Client project and a Server project. We are going to start with the Server project first. In this we will have to classes, a Main class (what starts the server and accepts clients) and a Client class (An object that we will set each client to through their socket). So I'm going to put the code up and then explain each important line and why we need it. (Some of the spacing, from copying and pasting, is off but I did my best to organize it.

Main.java:

Code: Select all

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;

public class Main {

	public static void main(String[] args) throws IOException {
		try 
		{
			final int PORT = 6677;
			ServerSocket server = new ServerSocket(PORT);
			System.out.println("Waiting for clients...");
		
			while (true)
			{												
				Socket s = server.accept();
				
				System.out.println("Client connected from " + s.getLocalAddress().getHostName());
				
				Client chat = new Client(s);
				Thread t = new Thread(chat);
				t.start();
			}
		} 
		catch (Exception e) 
		{
			System.out.println("An error occured.");
			e.printStackTrace();
		}
	}

}

So at the top we have our basic main method that runs the program and our imports, pretty basic and I'm not going to go over it.

The first thing that we start with is a try/catch and the reason we need this is because we need to bind the port to the server and that throws and Exception.

The next thing that we do is the following:

Code: Select all

final int PORT = 6677;
ServerSocket server = new ServerSocket(PORT);
System.out.println("Waiting for clients...");
What this does is first it creates a variable port and sets it to our port number. Then we make a new ServerSocket and bind it to our port variable. Then finally we print out that we are waiting clients.

The next thing that we have is a while loop which is practically saying while the program is running, do everything inside of it.

Then we have the main part which waits for a socket (client) to connect and when one does, it creates a new Client object with the parameter of the Socket

Code: Select all

Socket s = server.accept();
				
System.out.println("Client connected from " + s.getLocalAddress().getHostName());	
				
Client chat = new Client(s);
Thread t = new Thread(chat);
t.start();
At the first line we wait for a socket to connect and when one does we set it to the variable s. Then we print out the address they connected from just to let the server owner know when someone connects. After that we create our new Client object, which you will see soon, and then we create a new thread on the next like. Then we start the thread.

For those of you that don't know what a thread is, "a thread is a thread of execution in a program." (More Info) and a thread continuously runs until told to stop. You can also have multiple threads running at once and at the same time, not in the order of execution in the code.

Then at the end of the file we close all of the brackets and catch the exception if there is one.

So that is the end of the Main.java file. Now we are going to go to the Client.java file where all of the good stuff happens.

Client:

Code: Select all

import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;


public class Client implements Runnable{

	private Socket socket;
	
	public Client(Socket s)
	{
		socket = s;
	}
	
	@Override
	public void run()
	{
		try
		{
			Scanner in = new Scanner(socket.getInputStream());
			PrintWriter out = new PrintWriter(socket.getOutputStream());
			
			while (true)
			{		
				if (in.hasNext())
				{
					String input = in.nextLine();
					System.out.println("Client Said: " + input);
					out.println("You Said: " + input);
					out.flush();
				}
			}
		} 
		catch (Exception e)
		{
			e.printStackTrace();
		}	
	}

}

So that is the Client.java code and I'm going to explain the important lines starting at the top.

Before I get started with the main code, if you notice at the top next to "public class Client" we have an ending part which says "implements Runnable" and what that is doing is it is implementing the functions/methods in the Runnable interface and lets us use them in our code. This is what is needed for a thread. When a thread starts, it look for the run method and does everything inside of there over and over.

The first part is our constructor and our instance variable: socket:

Code: Select all

private Socket socket;								
	
public Client(Socket s)
{
	socket = s;											
}
So the reason we make a Socket instance variable is so that we can get the input and output streams of the client and send/get input to/from them. So what I did is I made a Socket as the parameter in then I set the instance variable, socket, to the value of s.

The next code we have is our run method which we implemented from the Runnable interface and it will run everything inside of it.

Then we have a try/catch which we need to use incase of the next part..

Code: Select all

Scanner in = new Scanner(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream());		
So what that is doing is it is getting the input and output streams and setting them to the variables in and out. These will be used to send and get data from the client. The reason we have that try/catch is because if the socket isnt set or their is a problem getting the input/output stream, it will throw an exception.

Finally we have our main code which gets the things the client has typed in, reads it, and resends it:

Code: Select all

while (true)
{		
	if (in.hasNext())
	{
		String input = in.nextLine();	
		System.out.println("Client Said: " + input);	
		out.println("You Said: " + input);				
		out.flush();				
	}
}
So what this code has is another while loop which is practically saying while the program is running do everything inside. Inside of it we have an 'if' statement which is saying if the client has typed something in and pressed enter, do everything inside. So inside first we set what they typed to a new String variable: input, we print out what they said, we sent it back to them with the out stream, and then we flush the out stream. If you don't flush it the message will never get sent (You can try that by commenting out the code).

Then at the end we catch if there is an exception and close all of the brackets.


So that is the end of Part 1, of the server, and good job on getting this far!


So now we are going to start working on the Client that connects to the server.

Part 2

So now is the start of part 2 and the Client project has the same two classes as the server, Main.java and Client.java. So first im going to start with the Main.java:

Code: Select all

import java.io.IOException;
import java.net.Socket;


public class Main {

	private final static int PORT = 6677;
	private final static String HOST = "localhost";
	
	public static void main(String[] args) throws IOException
	{
		try 
		{
			
			Socket s = new Socket(HOST, PORT);
			
			System.out.println("You connected to " + HOST);
			
			Client client = new Client(s);
			
			Thread t = new Thread(client);
			t.start();
			
		} 
		catch (Exception noServer)
		{
			System.out.println("The server might not be up at this time.");
			System.out.println("Please try again later.");
		}
	}
}

So at the top we have this code:

Code: Select all

private final static int PORT = 6677;
private final static String HOST = "localhost";
and what this is doing is creating two constant variables PORT and HOST and these will be used as the server ip and the port you will be connecting to.

Then we have a try/catch incase you don't connect to the server.

Inside of that we have the code that lets you connect to the server:

Code: Select all

Socket s = new Socket(HOST, PORT);			
			
System.out.println("You connected to " + HOST);		
			
Client client = new Client(s);					
			
Thread t = new Thread(client);
t.start();
The first line makes a new socket connected to the ip address of the HOST variable and the port of the PORT variable. After that we create a new Client Object with the parameter of the socket. Then we use that object and create a new thread to run whats inside of it.

So that is really the only thing in the Main.java class and now we can move onto the Client.java:

Code: Select all

import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client implements Runnable {

	private Socket socket;
	
	public Client(Socket s)
	{
		socket = s;
	}
	
	@Override
	public void run()
	{
		try
		{
			Scanner chat = new Scanner(System.in);	
			Scanner in = new Scanner(socket.getInputStream());	
			PrintWriter out = new PrintWriter(socket.getOutputStream());
			
			while (true)
			{						
				String input = chat.nextLine();
				out.println(input);	
				out.flush();
				
				if(in.hasNext())
					System.out.println(in.nextLine());
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		} 
	}

}
So at the top, just like in our server, we have our constructor set the instance variable: socket to the parameter Socket 's' so that we can get the input/output streams again. We also have the class implement the Runnable interface so that we can use it with a Thread.

Code: Select all

private Socket socket;										
	
public Client(Socket s)
{
	socket = s;												
}
Then we have our Run method and inside of that we start with a try/catch incase there is an exception with setting the input/output streams.

Then we have this code for the input/output:

Code: Select all

Scanner chat = new Scanner(System.in);						
Scanner in = new Scanner(socket.getInputStream());			
PrintWriter out = new PrintWriter(socket.getOutputStream());
So you probably recognize the bottom two lines of code which sets the variables in and out to the input and output streams of the socket to send/get data to/from the server. Then you see the first line which sets the Scanner variable chat to a new Scanner with the parameter of System.in. What this is doing is creating a variable to let the Client type things on the screen.

Then we have our main code which gets input from the client and sends it to the Server:

Code: Select all

while (true)										
{						
	String input = chat.nextLine();
					 
	out.println(input);								
	out.flush();								
				
	if(in.hasNext())								
		System.out.println(in.nextLine());				
}
So we have a while loop which runs anything inside of it over and over until the program stops, like a said 50 times :P. Then inside of that we set the String variable input to whatever the client types in. So if he doesnt type anything in, it will just sit there until he does and it wont do the rest of the code. Then we send out whatever they typed in to the client with the out stream. After that we flush the out stream and if we don't it wont send it completely. Then we have an 'if' statement which is saying if the server sent us something through the input stream then do the next line. What the next line is doing is simply printing out what the server sent us. Then after that we close all of the brackets and catch the exception if there is one.

And finally...

We are done!

So that is my little client and server program I made for you guys today. I hope you guys really liked it and I hope it helps you guys in the future!

~baseball435

Source Code: here
Virus Scan: here
Last edited by Baseball435 on Thu Nov 17, 2011 11:31 pm, edited 1 time in total.
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: [TUT] Server && Client Program

Post by Jackolantern »

Very nice! While I have changed project directions for the time-being (I plan to come back and work with WebSockets again in a couple of years once some issues get smoothed away and there are more tools and libraries for it), network programming still really interests me! Thanks for the nice tutorial :)
The indelible lord of tl;dr
Baseball435
Posts: 548
Joined: Sun May 30, 2010 3:49 am

Re: [TUT] Server && Client Program

Post by Baseball435 »

Yeah I love network programming and thought some people here might, thanks for the feedback :D
User avatar
Jackolantern
Posts: 10891
Joined: Wed Jul 01, 2009 11:00 pm

Re: [TUT] Server && Client Program

Post by Jackolantern »

Woot! Congrats on 500 posts!
The indelible lord of tl;dr
Baseball435
Posts: 548
Joined: Sun May 30, 2010 3:49 am

Re: [TUT] Server && Client Program

Post by Baseball435 »

Didnt even realize it! Thanks :D
stefans
Posts: 48
Joined: Wed Sep 14, 2011 7:14 pm

Re: [TUT] Server && Client Program

Post by stefans »

Nice tutorial,
but it would be more helpfull if you made something that the server doesn't only say: you said: ..
but sends to all other clients: (ip) said: ... or something like that
Current project: http://www.mmtycoon.eu
Post Reply

Return to “Tutorials”