Page 1 of 1

Simple Client and Server Chat Program Rate Topic: -----

#1 baseball435  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 4
  • View blog
  • Posts: 68
  • Joined: 30-November 09

Posted 08 January 2012 - 02:43 PM

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. 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:
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;//SET NEW CONSTANT VARIABLE: PORT
			ServerSocket server = new ServerSocket(PORT); //SET PORT NUMBER
			System.out.println("Waiting for clients...");//AT THE START PRINT THIS
		
			while (true)//WHILE THE PROGRAM IS RUNNING
			{												
				Socket s = server.accept();//ACCEPT SOCKETS(CLIENTS) TRYING TO CONNECT
				
				System.out.println("Client connected from " + s.getLocalAddress().getHostName());	//	TELL THEM THAT THE CLIENT CONNECTED
				
				Client chat = new Client(s);//CREATE A NEW CLIENT OBJECT
				Thread t = new Thread(chat);//MAKE A NEW THREAD
				t.start();//START THE THREAD
			}
		} 
		catch (Exception e) 
		{
			System.out.println("An error occured.");//IF AN ERROR OCCURED THEN PRINT IT
                        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:
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
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." (http://download.orac...ang/Thread.html) 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.


[/HR]

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:
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;


public class Client implements Runnable{

	private Socket socket;//SOCKET INSTANCE VARIABLE
	
	public Client(Socket s)
	{
		socket = s;//INSTANTIATE THE SOCKET
	}
	
	@Override
	public void run() //(IMPLEMENTED FROM THE RUNNABLE INTERFACE)
	{
		try //HAVE TO HAVE THIS FOR THE in AND out VARIABLES
		{
			Scanner in = new Scanner(socket.getInputStream());//GET THE SOCKETS INPUT STREAM (THE STREAM THAT YOU WILL GET WHAT THEY TYPE FROM)
			PrintWriter out = new PrintWriter(socket.getOutputStream());//GET THE SOCKETS OUTPUT STREAM (THE STREAM YOU WILL SEND INFORMATION TO THEM FROM)
			
			while (true)//WHILE THE PROGRAM IS RUNNING
			{		
				if (in.hasNext())
				{
					String input = in.nextLine();//IF THERE IS INPUT THEN MAKE A NEW VARIABLE input AND READ WHAT THEY TYPED
					System.out.println("Client Said: " + input);//PRINT IT OUT TO THE SCREEN
					out.println("You Said: " + input);//RESEND IT TO THE CLIENT
					out.flush();//FLUSH THE STREAM
				}
			}
		} 
		catch (Exception e)
		{
			e.printStackTrace();//MOST LIKELY THERE WONT BE AN ERROR BUT ITS GOOD TO CATCH
		}	
	}

}




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:
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..
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:
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.


[/HR]

So that is the end of Part 1 and 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:

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


public class Main {

	private final static int PORT = 6677;//SET A CONSTANT VARIABLE PORT
	private final static String HOST = "localhost";//SET A CONSTANT VARIABLE HOST
	
	public static void main(String[] args) throws IOException
	{
		try 
		{
			
			Socket s = new Socket(HOST, PORT);//CONNECT TO THE SERVER
			
			System.out.println("You connected to " + HOST);//IF CONNECTED THEN PRINT IT OUT
			
			Client client = new Client(s);//START NEW CLIENT OBJECT
			
			Thread t = new Thread(client);//INITIATE NEW THREAD
			t.start();//START THREAD
			
		} 
		catch (Exception noServer)//IF DIDNT CONNECT PRINT THAT THEY DIDNT
		{
			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:
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:
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:
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client implements Runnable {

	private Socket socket;//MAKE SOCKET INSTANCE VARIABLE
	
	public Client(Socket s)
	{
		socket = s;//INSTANTIATE THE INSTANCE VARIABLE
	}
	
	@Override
	public void run()//INHERIT THE RUN METHOD FROM THE Runnable INTERFACE
	{
		try
		{
			Scanner chat = new Scanner(System.in);//GET THE INPUT FROM THE CMD
			Scanner in = new Scanner(socket.getInputStream());//GET THE CLIENTS INPUT STREAM (USED TO READ DATA SENT FROM THE SERVER)
			PrintWriter out = new PrintWriter(socket.getOutputStream());//GET THE CLIENTS OUTPUT STREAM (USED TO SEND DATA TO THE SERVER)
			
			while (true)//WHILE THE PROGRAM IS RUNNING
			{						
				String input = chat.nextLine();	//SET NEW VARIABLE input TO THE VALUE OF WHAT THE CLIENT TYPED IN
				out.println(input);//SEND IT TO THE SERVER
				out.flush();//FLUSH THE STREAM
				
				if(in.hasNext())//IF THE SERVER SENT US SOMETHING
					System.out.println(in.nextLine());//PRINT IT OUT
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();//MOST LIKELY WONT BE AN ERROR, GOOD PRACTICE TO CATCH THOUGH
		} 
	}

}



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.
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:
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:
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!


[/HR]

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!

|Credits|
baseball435

Is This A Good Question/Topic? 0
  • +

Replies To: Simple Client and Server Chat Program

#2 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8334
  • View blog
  • Posts: 31,858
  • Joined: 06-March 08

Posted 25 January 2012 - 10:30 PM

Your 2 while(true) like this one

while (true)
{		
	if (in.hasNext())
	{
		String input = in.nextLine();	
		System.out.println("Client Said: " + input);	
		out.println("You Said: " + input);				
		out.flush();				
	}
}



Are real CPU grabber, will actually completly occupy one CPU (if your PC has more than one) on your system.
Why can't you just
String input = in.nextLine();
and wait there for user input ?

Where does your Server stores the list of all its Clients so it can distribute the messages received. Seems that your code for only one Client :)

This post has been edited by pbl: 25 January 2012 - 10:42 PM

Was This Post Helpful? 2
  • +
  • -

#3 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2735
  • View blog
  • Posts: 11,521
  • Joined: 20-September 08

Posted 21 February 2012 - 03:29 PM

Probably better to use either List<char[]> or List<String[]>
Was This Post Helpful? 0
  • +
  • -

#4 cuti144  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 18-March 12

Posted 18 March 2012 - 03:50 PM

May I ask you all a question. For most of the server/client chat tutorial they use the same class for multiple clients. But if I have two separate classes and each of them have a GUI, how can I connect them through the server. Sorry for being stupid :P
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1