Download Server.Java

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
ACKNOWLEDGEMENTS
Firstly, we owe an enormous dept of gratitude to my project
supervisor, Dan Witzner Hansen for guiding and inspiring us from the
beginning through the end of this project with his intellectual advices
and insightful suggestions. We truly appreciate and value his
consistent feedback on our progress which was always constructive
and encouraging and ultimately droved me to the right direction.
We also owe a great deal of thanks to several people from IT
University of Copenhagen for their help.
Naveed Anjum
Sridher Rao Sidduri
1
CHAPTER # 1
1.1 INTRODUCTION
This report is based on the project (CHAT ROOM) carried out by us
(naveed anjum and sridher) with the supervisor (DAN WITZNER
HANSEN). The basic idea is to develop an application facilitating the clients
to chat with each other through the server.
During this project we improved our knowledge obtained in Internet
technology/Multimedia technology by combining the two subjects
introduction to java and networking and protocols. We enhanced our
practical knowledge by analyzing how work is being done in the real world.
1.2 DESCRIPTION and STUDY PHASE:
During the study phase many options were under discussion.
1.single client chat
Client
client
2.chat among all the clients without the server
client
client
client
client
2
3.chat among the clients through server
Server
Client 3
Client 2
Client 1
The third design was agreed to work on due to the following reasons.
1 Server performs some functions in the central manner and it has the
control over all the clients.
2 Using the Server/Client model facilitates resource sharing. Instead of
giving resources to all the clients its enough to have all the resources on the
server and share them among the clients.
3 Our Server/Client model is good for authorization and authentication as
the server maintains the list of all allowed users and illegal access to the
system by the clients is prohibited.
3
CHAPTER#2




REQUIRED KNOWLEDGE
TCP/IP SOCKETS AND JAVA
THREADS
SYNCHORONIZATION
JAVA SWINGS
2.1 TCP/IP SOCKETS AND JAVA
Every network application in java consists of mainly two programs
Client program
Server program
When these two programs are executed ,client and server processes are
created and they communicate with each other by reading from and writing
to the sockets. Thus socket is a gateway between client and server processes.
IP is a lower level protocol , it brakes data into data chunks and pass it to the
socket . IP is always on the payload of TCP which assures reliable data
transfer.
internet socket
host
internet
socket
host
when the client process initiates by creating its socket ,it knocks at the
door(server socket) of server. When the server hears the knocking ,it creates
a new door (socket) and dedicates it to the client.
Thus a server process has always many sockets specific with each clients.
When a client makes a connection ,it always should know two things
Server name or host address
Port number
Initiating the client socket specifies the host address and port number where
communication is going to be made.
In our case ,we have server not only listning clients but also broadcasting
the messege to all online users.
4
Furthermore a unique thread cares each socket. Thus we can save the
host from going into deadlock. Breaf discussion is coming in the next
chapter.
Here to define a little bit that our chat application is mainly a chat
room. Private chat and different status of online users are kept in extension.
These features could be added after a small change in the application.
Instead of reading string messages from and writing string messages to the
socket we used objects. Objects are being passed to the sockets so that
further extensions could be made after a little change in the main program.
2.2 THREADS
In the chat application, we controlled parallelism and
concurrency by implementing the multithreading concept defined in java
programming.” A thread is a single sequential flow of control within a
program”. Thread has a beginning, sequence and end. However, a thread
itself is not a program; it cannot run on its own. Rather, it runs within a
program.
During the work we improved our knowledge on threads by implementing
the different states of threads.
NEW:
It has just been created just like another object, but it has not yet been
set as runnable by means of the start method.
RUNNING:
It means it is executing the instructions written in the run method.
RUNNABLE:
It is able to run but some other threads are running at the same
time. So the thread is in waiting status.
BLOCKED:
Thread has been suspended for a number of milliseconds due to
its sleep method have been invoked.
5
Brief explanation of how the threads work in our chat application is coming
in the design and implementation phase.
2.3 SYNCHORONIZATION
Multithreaded programs are often needed to be
synchronized to ensure that two methods will not run at the same time when
two or more threads need access to the shared resources.
In our chat application we came to know the fact that accessing the
server by many threads (objects) needs to be synchronized. We used
synchronized method to ensure the synchronization in our chat application.
Synchronized (server.getList ()
Synchronized (server.getOut ()
Already locked
by another
thread
Try to
enter
Waiting for
lock
Unlock by another
thread
Lock
obtained by
this thread
running
Notify()by
anther thread
Waiting for
notify()
Wait() by this
therad
Unlokc by this thread
6
2.4 JAVA SWINGS AND AWT
We used both AWT and SWINGS to make GUI for the chat
application. Two most common windows PANEL and FRAME are used in
the project. Some of the stuff from SWINGS.
Commonly used AWT classes in the project and their description is as
follows.
 FRAME: creates a standard window that has a little bar,resize corners
and a menu bar.
 EVENT: encapsulates events.
 COMPONENT: an abstract superclass for various awt components.
 CONTAINER: a sub class of component that can hold other
components.
 BUTTON: creates a push button control.
 BORDERLAYOUT: border layout manager. It use five
Components.north, south, east, west and center.
 GRIDBAGLAYOUT: displays components subject to the constraints
specified by GRIDBAGLAYOUTCONSTRAINTS.
 LABEL: creates a label that displays a string.
 LIST: creates a list from which online users can be chosen.
 TEXT AREA: creates a multilane edit control.
 TEXTFIELD: creates a single line edit control.
7
CHAPTER# 3
DESIGN AND DATAMODEL
3.1 INTRODUCTION OF OUR SERVER CLIENT MODEL:
In our server client model one computer is server and all other
machines are clients. Server has much storage space and efficient
mechanisms to respond all the clients quickly. It has also a sufficient
processing power to run the network operating system and
applications. Clients connect to the server to share the resources and
interact among each other through the network. A powerful server can
handle hundreds of thousands of users at a time.
3.2 BRIEF DATAMODEL IN FOUR STEPS
STEP #1: single user
8
Client
server
USERS
Logon with username
If user is not logged in before
and logged out =false
List of
online
users
Welcome (connected)
 Client sends connection request with his name.
 Server checks if client has not been logged in before
 If not it sends welcome message to the client along with the online
users list.
 Shows client status on the server.
STEP #2: multiusers
Client
server
C1
logged user
C2
login request
users
Update user list
Update list
C1
C2
C1
Welcome(connected)+ list
C2
9
STEP #3: sending message
Server
Client
server
Sending message
Assign
thread
to
every
client
C1
C2
Server receiver
Run ()
C1
message
message
C2
Broadcaster
message
In the above step we considered that clients c1 and c2 are connected before.
 When clients send message to the server, server assigns a thread to
each client
 Through the method run () we already has sent welcome message to
all the online users.
 We started an object of class broadcaster in the run () method, thus
passed those messages to the broadcaster, which broadcast them to
further two online clients and on the server.
10
STEP #4:
logging out
Client
Logging out
c
server
Isloggedout=true
Messa
ge
Server receiver
If true
Logged out
 Client sends logging out message
 Server checks if isloggedout variable value is true
 If value is true it sends logged out message with the client name on
server and to all the online clients.
11
CHAPTER #4
EXPLANATION OF CLASS METHODS
4.1 WHAT DOES OUR SERVER DO:
In our client server environment, server is the main device, receives
client requests and responds immediately. Server performs some functions in
central manner rather then having those function distributed throughout the
network or on the clients.
Main (server. java)
Client
Client
Message buffer
Broad
caster
User
Client
Online
users
list
Server
receiver
Messages being broadcasted
12
4.2 Main functions of server





Receives client’s request
Accepts or rejects connection
Updates online user’s list
Shows online users on server screen
Broadcasts message
4.3 MAIN CLASSES OF SERVER
 SERVER.JAVA
 USERS.JAVA
 MESSAGE.JAVA
 SERVER RECEIVER.JAVA
 BROADCASTER.JAVA
In our client server chat environment, our main server class (server. java)
supervises the whole process. For this we initiated a server socket,
continuously listening to the clients. Server checks if the user is already
online. If not, it passes this online users name to the user’s list, and sends
welcome message back to the client through the broadcaster. This client is
assigned a thread by the server and the server goes back to listen other
clients. Once a client is accepted the dedicated socket between server and
client is created. Server receiver class reads clients message and inserts this
message in the client buffer (MESSAGE.JAVA). Then Broadcaster class
gets message out and sends it to all clients through sockets and broadcast the
upgraded User List when change occurs. Multi threading is necessary here to
enable server to listen multiple clients and response concurrently. For this
purpose we need to maintain the server state.
Users. Java class maintains the state of online users. We are passing array to
the class Users. Java, containing information on users state.
We need to guarantee that the same user cannot be logged at the same time,
for this we are checking the value of “logged on” variable which is set to
false if the user is not logged on already.
13
Another important point is that the methods should be synchronized to
guarantee state would be updated (client being added or removed from the
list and releases a place in the User List) concurrently.
Class message. Java: is used to store and get messages communicated
among clients and server. Synchronization is needed, as Buffer is a shared
object among all users,
Class jusers.java: mainly inserts a new client in the list array. The array list
is checked and the new client is inserted in the first available position that is
available.
Class server Receiver: is very important class of server. RUN( )method of
thread is being started here. Explanation of important methods of server
receiver is as follows.
When Server Socket accepts client’s initial request. The first input stream
message from client is the username. ServerReceiver reads the username
first and checks the current Status of Userlist . If the name is already
registered, it sends notification message to the client and closes the
connection.
If the name is not registered, ServerReceiver accepts the connection by
adding the name in the Userslist, and then sends a welcome message to the
client. ServerReceiver continues reading messages from the client.
After the connection, that is, dedicated socket, is established,
ServerReceiver receives message from client “logging on”, it will be added
with “username ” and put into message buffer for Broadcaster thread to
execute accordingly.
Broadcaster is another thread class. It gets the message from message
Buffer and gets State of all Users. If the message is the notification message
from a client about his logging on “ is logging on” or logging out “is logging
out”, Broadcaster calls method which upgrade the UserList by deleting
username (we have already added the user who logs on at ServerReceiver,
we do not need to upgrade UserList when receiving logging on
message.)and broadcasts to all the users in the UserList.. Otherwise the
message is broadcasted.
14
4.4 WHAT DOES OUR CLEINT DO:
4.5 MAIN FUNCTIONS OF OUR CLIENT:
 Out client request s connection to the known server, giving IP
address and port number.
 Gets user message from the text box and sends to the server.
 Receives message from the server and put into the response text area.
 When logout button is clicked, acknowledges server to close the
socket.
4.6 MAIN COMPONENTS OF OUR CLIENT WINDOW:
 SERVER ADDRESS
 USER NAME
 ONLINE USERS LIST
 MESSAGE
 RESPONSE
 BUTTONS
4.7 Main components of our client:
Our client is mainly a user interface with four click events on the buttons,
class receiver and a class terminated.
BUTTONS:
LOGON: connection establishment script is written on the click event of
this button.
SEND: script on the click event of this button cares of sending messages to
the server.
LOGOUT: event of this button is captured when a user wants to logout.
RECEIVER CLASS:
RECEIVER CLASS is a thread performing two tasks.
 Receiving messages from the server (message class) and appending
those messages into the response text area.
 Getting array list from the server (users class) and showing online
users on the client window.
TERMINATED CLASS:
This class is to set client in an active state when it is online. The methods
here need to be synchronized.
15
CHAPTER #5
IMPLEMENTATION
We have already explained the methods and classes in detail.
Implementation is mainly being done by the server methods and classes.
Here we are showing USER INTERFACE only to clear the implementation
phase of our project.
This is our main user interface that appears after the compilation of
Client.java. Usernames are being generated randomly by Rand method.
The user with randomly generated username will be logged in by clicking
Logon button in the window. A message is being shown on the client as
soon as the connection to the server is successful. A welcome message
confirming that the user is connected is also displayed on the server screen
as below.
16
Now the second client is connected with the upgraded user list. The server is
displaying the status of the second online user. Now we can observe the
updated server window.
17
Now we will see how the message is being sent from one user to other user.
18
The message is being sent from the first user to the second user. We can also
see the reply sent by the second user to the first user as follows.
19
We can also see the screen shots for logging out a user.
The information of the user logging out will also be shown on the server
window as well as on the other client’s session as below.
20
These are the screen shots we got by compiling that explains briefly how the
program is working.
21
CHAPTER #6
FUTURE ENHANCEMENTS AND CONCLUSIONS:
6.1 Enhancements:This project can also be extended with many features such as
1) We could also have extended this project with private chatting feature
if we had enough time.
2) We can also send the messages with different colors according to the
message type.
3) Sending some alerts for different types of messages would be one of
the enhancements.
6.2 Conclusion:In this project we could able to learn AWT package explaining how to make
the user interfaces. We practically worked on Java Sockets and
implementing using the GUI. We could able to learn threading concept in
practical scenario. We learned passing the arrays in the sockets and keeping
the state of the users in record by using hash table and Jlists. We can now go
further projects with this accumulated knowledge.
22
6.3 References:
1. The complete reference/java2 written by Herbert schildt
2. Java for students by Douglas Bell
3. Networking and protocols by James F. Kurose
4. Core Java vol-2 by Cay Horstmann and Gary Cornell
5. www.cs.drexel.edu
6. www.itu.dk/`witzner
7. www.ndu.edu.lb
23
CHAPTER #7
Project code:
Client.java
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
public class Client {
public static void main(String[] args) {
JFrame frame = new MailTestFrame();
frame.show();
}
}
class MailTestFrame extends JFrame implements ActionListener {
public MailTestFrame() {
setTitle("Chat Client");
setSize(300, 300);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
getContentPane().setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 0;
gbc.weighty = 0;
gbc.weightx = 0;
add(new JLabel("Server:"), gbc, 0, 0, 1, 1);
gbc.weightx = 100;
serverAdr = new JTextField(20);
add(serverAdr, gbc, 1, 0, 1, 1);
24
gbc.weightx = 0;
add(new JLabel("Username:"), gbc, 0, 1, 1, 1);
gbc.weightx = 100;
userName = new JTextField(20);
add(userName, gbc, 1, 1, 1, 1);
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 100;
message = new JTextArea();
add(new JScrollPane(message), gbc, 0, 3, 2, 1);
response = new JTextArea();
add(new JScrollPane(response), gbc, 0, 4, 2, 1);
gbc.weighty = 0;
JButton sendButton = new JButton("Send");
sendButton.addActionListener(this);
JPanel buttonPanel = new JPanel();
buttonPanel.add(sendButton);
add(buttonPanel, gbc, 0, 5, 2, 1);
JButton logonButton = new JButton("Logon");
logonButton.addActionListener(this);
buttonPanel.add(logonButton);
add(buttonPanel, gbc, 0, 6, 2, 1);
JButton logoutButton = new JButton("Logout");
logoutButton.addActionListener(this);
buttonPanel.add(logoutButton);
add(buttonPanel, gbc, 0, 7, 2, 1);
dataList = new JList(new Vector());
getContentPane().add(dataList);
this.serverAdr.setText("localhost");
this.userName.setText(Integer.toString(new Random().nextInt()));
}
private void add(Component c, GridBagConstraints gbc, int x, int y, int w, int h) {
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = w;
gbc.gridheight = h;
getContentPane().add(c, gbc);
}
25
public void actionPerformed(ActionEvent evt) {
Terminated term = new Terminated();
String str = evt.getActionCommand();
try {
if (str.equals("Send")) {
String msg = message.getText();
Message m = new Message(msg);
oos.writeObject(m);
oos.flush();
message.setText("");
System.out.println(" message has been send ");
}
if (str.equals("Logon")) {
if (!logedOn) {
message.setText("");
response.setText("");
s = new Socket(serverAdr.getText(), 8888);
oos = new
ObjectOutputStream(s.getOutputStream());
oos.writeObject(new Users(userName.getText()));
oos.flush();
ois = new ObjectInputStream(s.getInputStream());
Message m= (Message)ois.readObject();
String msg = m.getMessage();
if (msg.equals("Welcome"))
response.append("Connected To Server
Successfully.");
else {
s.close();
throw new Exception("Invalid or Already
Existing Username.");
}
user = userName.getText();
logedOn = true;
ArrayList users = (ArrayList)ois.readObject();
26
dataList.setListData(users.toArray());
new Receiver(response, ois, t, dataList).start();
}
}
if (str.equals("Logout")) {
Message m = new Message(user);
m.setLogout(true);
oos.writeObject(m);
oos.flush();
logedOn = false;
t.done();
s.close();
}
}
catch (Exception e) {
response.append("Error: " + e);
}
}
private String user = "John Doe";
private JTextField serverAdr;
private JTextField userName;
private JTextArea message;
private JTextArea response;
private Socket s;
private ObjectOutputStream oos;
private boolean logedOn;
private ObjectInputStream ois;
private JList dataList;
Terminated t = new Terminated();
public ArrayList getArray(String s) {
ArrayList list = new ArrayList();
StringTokenizer st = new StringTokenizer(s, ";");
while (st.hasMoreTokens()) {
list.add(st.nextToken());
27
}
return list;
}
}
class Receiver extends Thread {
JTextArea response;
ObjectInputStream ois;
Terminated term;
JList userList;
public Receiver(JTextArea j, ObjectInputStream ois, Terminated t, JList userList)
{
response = j;
this.ois = ois;
term = t;
userList = userList;
}
public void run() {
try {
Message m = null;
while (!term.isDone()){
if ((m= (Message)ois.readObject()) != null) {
response.append("\n" + (m.getMessage()));
}
else
{
ArrayList users = (ArrayList)ois.readObject();
userList.setListData(users.toArray());
}
}
}
catch (Exception e) {
System.out.println(e);
}
}
}
//------------------------------------class Terminated {
private boolean done = false;
28
public synchronized void done() {
done = true;
}
public synchronized boolean isDone() {
return done;
}
}
Server.Java
import java.io.*;
import java.net.*;
import java.util.*;
//------------------------------------------------------------------public class Server {
static State state = new State();
private HashMap hashlist = new HashMap();
private PrintStream pw;
public static ArrayList users;
public void startServer() throws Exception {
this.users = new ArrayList();
PipedWriter piw = new PipedWriter();
PipedReader pir = new PipedReader(piw);
pw = System.out;
ServerSocket ssoc = new ServerSocket(8888);
while (true)
new Thread(new ServerReceiver(this, ssoc.accept())).start();
}
public PrintStream getOut() {
return pw;
}
public HashMap getList() {
return hashlist;
}
29
public static void main(String[] args) throws Exception {
new Server().startServer();
}
}
//------------------------------------------------------------------class State {
public synchronized void newUser() {
}
public synchronized void deleteUser() {
}
public synchronized void getAllUsers() {
}
}
Message.Java
import java.io.Serializable;
public class Message implements Serializable {
private String message;
private boolean logout = false;
public Message(String m){
this.message = m;
}
public String getMessage() {
return message;
}
public void setMessage(String string) {
message = string;
}
public boolean isLogout() {
return logout;
}
public void setLogout(boolean b) {
logout = b;
}
}
30
Broadcaster.Java
import java.io.*;
import java.net.*;
import java.util.*;
class Broadcast {
private Server server;
private Message m;
public Broadcast(Server server, Message m) {
this.m = m;
this.server = server;
}
public void sendMessage() {
try {
String mess;
HashMap list = server.getList();
//while ((mess = in.readLine()) != null) {
synchronized (list) {
Iterator entries = list.keySet().iterator();
while (entries.hasNext()) {
try {
ObjectOutputStream oos =
(ObjectOutputStream) list.get((String) entries.next());
oos.writeObject(m);
oos.flush();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
31
public void sendUsersList() {
try {
String mess;
HashMap list = server.getList();
//while ((mess = in.readLine()) != null) {
synchronized (list) {
Iterator entries = list.keySet().iterator();
while (entries.hasNext()) {
try {
ObjectOutputStream oos =
(ObjectOutputStream) list.get((String) entries.next());
oos.writeObject(server.users);
oos.flush();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
ServerReceiver.Java
import java.io.*;
import java.net.*;
import java.util.*;
class ServerReceiver extends Thread {
private ObjectInputStream ois;
private ObjectOutputStream oos;
private Server server;
private String name;
private InputStream is ;
private OutputStream os ;
32
ServerReceiver(Server server, Socket s) throws Exception {
this.server = server;
is = s.getInputStream();
os = s.getOutputStream();
}
public void run() {
try {
ois = new ObjectInputStream(is);
oos = new ObjectOutputStream(os);
name = ((Users)ois.readObject()).getUser();
name = name.trim();
if (name.length() == 0 || server.getList().containsKey(name) ||
name.equals("#")) {
oos.writeObject(new Message("Invalid Name"));
oos.flush();
name = "#";
return;
}
synchronized (server.getList()) {
server.getList().put(name, oos);
server.users.add(name);
}
synchronized (server.getOut()) {
server.getOut().println(name + " comes into chat.");
}
System.out.println(name + " connected");
oos.writeObject(new Message("Welcome"));
oos.flush();
oos.writeObject(server.users);
oos.flush();
String mess;
Message m;
while ((m= (Message)ois.readObject()) != null) {
if (m.isLogout()==true)
mess = m.getMessage() + " is loggedout " ;
33
else
mess = name + "> " + m.getMessage();
Broadcast bc = new Broadcast(this.server, new
Message(mess));
bc.sendMessage();
synchronized (server.getOut()) {
server.getOut().println(mess);
}
if (m.isLogout()==true)
{
return;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (!name.equals("#")) {
System.out.println(name + " disconnected");
server.getList().remove(name);
try {
synchronized (server.getOut()) {
server.getOut().println(name + " went off
the chatt.");
}
Broadcast bc = new Broadcast(this.server, null);
bc.sendUsersList();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void userWentOff(String s){
if (!name.equals("#")) {
System.out.println(name + s);
server.getList().remove(name);
try {
synchronized (server.getOut()) {
34
server.getOut().println(name + " went off
the chatt.");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
JUsers.Java
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
public class JUsers extends JFrame implements ActionListener{
private JList dataList;
public JUsers(ArrayList data){
setTitle("Login Users");
setSize(300, 300);
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);
}
} );
dataList = new JList(new Vector(data));
getContentPane().add(dataList);
}
private void add(Component c, GridBagConstraints gbc, int x, int y, int w, int h){
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = w;
gbc.gridheight = h;
getContentPane().add(c, gbc);
35
}
public void actionPerformed(ActionEvent evt){
}
}// class
Users.Java
import java.io.Serializable;
import java.util.ArrayList;
public class Users implements Serializable {
private ArrayList users;
private String loggedUser;
public Users(String userName){
this.loggedUser = userName;
}
public Users(ArrayList users){
this.users = users;
}
public String getUser(){
return this.loggedUser;
}
public ArrayList getUsers(){
return this.users;
}
}
36