Professional Documents
Culture Documents
Project Title:-
Multiple Client-Server Chatting and
Sharing System
Members:-
16MIS0187-K.Gopi Krishna
16MIS0320-G.Nagendra babu
16MIS0364-N.Pavan Kalyan
Faculty:-Uma.K Slot:-B1+TB1
Table of Contents
1 Introduction..............................................................................................3
1.1 Problem definition ...............................................................................3
1.2 Project description ...............................................................................3
1.3 Statement of scope ...............................................................................4
2 Technical background ............................................................................. 5
2.1 Instant messengers ...............................................................................5
2.2 Java ..................................................................................................... 5
3 System architecture ................................................................................. 6
3.1 Overview............................................................................................. 6
3.2 The client ............................................................................................ 6
3.3 The server ........................................................................................... 8
3.4 The administrator .................................................................................8
3.5 The database ....................................................................................... 9
4 Design and implementation details....................................................... 10
4.1 SSL Sockets ...................................................................................... 10
4.2 GUI Design ....................................................................................... 11
4.3 Implemented features........................................................................ 11
4.4 The Protocol...................................................................................... 12
5 Conclusion ............................................................................................ 14
6 Future work ........................................................................................... 14
7 References ............................................................................................. 15
1 Introduction
2.2 Java
This project is written entirely in J2SE 1.5 (Source 1) and takes advantage of
the following packages:
● javax.swing.* - GUI.
3.1 Overview
The complete overview over the system can be seen in figure 1. The clients
can connect to each other, as well as connect to the server and communicate
through this. The server runs as a standalone applications but can be controlled
by the administrator. User information and information about banned IP
addresses is stored in the database.
Controller
Managers
Figure 3 shows the 3 different types of traffic handled by the managers. Figure
4 shows the internal structure of the managers. The protocol is implemented
at the level of the sender/receiver and the reader/writer.
Figure 3: Client
traffic.
Figure 4: Manager handling (left) file transfers
and (right) text traffic.
The server
The server does not have any GUI components, thus simple in many ways. At
the top there is a controller. The controller handles the database, the
adminlistener and the clientlistener, and all interaction between those classes.
The server listens for incoming clients (multiple) and incoming administrator
(only one), but does not initiate any outgoing traffic. (Figure 5)
Figure 5: The
server
import java.net.*;
import javax.net.ssl.*;
SSLServerSocket ss = null;
ss = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket
(CLIENTLISTEN_PORT);
ss.setNeedClientAuth(false);
String cipherSuite [] = {"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"};
ss.setEnabledCipherSuites(cipherSuite);
Socket tmp_socket = ss.accept();
import javax.net.ssl.*;
o BoxLayout
o JFrame
o JPanel
java.awt
o BorderLayout
o FlowLayout
o GridBagLayout
o GridLayout
Other than that general graphical editing software have been used for creating
icons and images etc.
o Monitoring, being able to see which users are online and which
are offline, also monitoring events.
o Banning IP addresses and seeing which IP addresses are banned.
File transactions
o <Filename> - Name of file.
o <Filesize> - Filesize in bytes.
o TACC – Accept filetransfer.
o TDEN – Deny filetransfer.
o 1<100010010101…> - As file is sent (raw bytes) each block
transaction must be started with 1 to indicate healthy
connection.
TESTING PROCESS
Testing is the process of checking the functionality of an application to
ensure it runs as per requirements. Unit testing comes into picture at the
developers’ level; it is the testing of single entity (class or method). Unit testing
plays a critical role in helping a software company deliver quality products to its
customers.
Unit testing is a software development process in which the smallest testable
parts of an application, called units, are individually and independently
scrutinized for proper operation. Unit testing is often automated but it can also
be done manually.
Unit testing is commonly automated, but may still be performed manually.
The IEEE does not favor one over the other. The objective in unit testing is to
isolate a unit and validate its correctness. A manual approach to unit testing may
employ a step-by-step instructional document. However, automation is efficient
for achieving this, and enables the many benefits listed in this article.
Conversely, if not planned carefully, a careless manual unit test case may
execute as an integration test case that involves many software components, and
thus preclude the achievement of most if not all of the goals established for unit
testing.
Advantages
The goal of unit testing is to isolate each part of the program and show
that the individual parts are correct. A unit test provides a strict, written contract
that the piece of code must satisfy. As a result, it affords several benefits.
Find problems early
Unit testing finds problems early in the development cycle. This includes
both bugs in the programmer's implementation and flaws or missing parts of the
specification for the unit. The process of writing a thorough set of tests forces
the author to think through inputs, outputs, and error conditions, and thus more
crisply define the unit's desired behavior. The cost of finding a bug before
coding begins or when the code is first written is considerably lower than the
cost of detecting, identifying, and correcting the bug later; bugs may also cause
problems for the endusers of the software. Code can be impossible or difficult to
test if poorly written, thus unit testing can force developers to structure functions
and objects in better ways.
In test-driven development (TDD), which is frequently used in both extreme
programming and scrum, unit tests are created before the code itself is written.
When the tests pass, that code is considered complete. The same unit tests are
run against that function frequently as the larger code base is developed either as
the code is changed or via an automated process with the build. If the unit tests
fail, it is considered to be a bug either in the changed code or the tests
themselves. The unit tests then allow the location of the fault or failure to be
easily traced. Since the unit tests alert the development team of the problem
before handing the code off to testers or clients, it is still early in the
development process.
Facilitates change
Unit testing allows the programmer to refactor code or upgrade system
libraries at a later date, and make sure the module still works correctly like in
regression testing. The procedure is to write test cases for all functions and
methods so that whenever a change causes a fault, it can be quickly identified.
Unit tests detect changes which may break a design contract.
Simplifies integration
Unit testing may reduce uncertainty in the units themselves and can be used
in a bottom-up testing style approach. By testing the parts of a program first and
then testing the sum of its parts, integration testing becomes much easier.
Design
When software is developed using a test-driven approach, the combination of
writing the unit test to specify the interface plus the refactoring activities
performed after the test is passing, may take the place of formal design. Each
unit test can be seen as a design element specifying classes, methods, and
observable behavior.
Unit testing can be done in two ways − manual testing and automated
testing.
Manual Testing
Executing a test cases manually without any tool support is known as manual
testing.
Time-consuming and tedious − Since test cases are executed by human
resources, it is very slow and tedious.
Huge investment in human resources − As test cases need to be executed
manually, more testers are required in manual testing.
Less reliable − Manual testing is less reliable, as it has to account for
human errors.
Non-programmable − No programming can be done to write sophisticated
tests to fetch hidden information.
Automated Testing
Taking tool support and executing the test cases by using an automation
tool is known as automation testing.
Fast − Automation runs test cases significantly faster than human
resources.
Less investment in human resources − Test cases are executed using
automation tools, so less number of testers are required in automation
testing.
More reliable − Automation tests are precise and reliable.
Programmable − Testers can program sophisticated tests to bring out
hidden information.
TEST CASE
• A Unit Test Case is a part of code, which ensures that another part of
code (method) works as expected. To achieve the desired results
quickly, a test framework is required. JUnit is a perfect unit test
framework for Java programming language.
• A formal written unit test case is characterized by a known input and an
expected output, which is worked out before the test is executed. The
known input should test a precondition and the expected output should
test a post-condition.
• There must be at least two unit test cases for each requirement − one
positive test and one negative test. If a requirement has
subrequirements, each sub-requirement must have at least two test cases
as positive and negative.
Test Cases Prepared for Sign Up, Database, Message & File Transfer
Modules
Sign Up Process:
For Sign Up, You must submit Username & Password Fields
Test Case Table for Sign Up Module:
Test Test Case Test Test Expected Actual Stat Remarks
Case ID Description Executio Inputs Result Result us
n Steps
‘Usernam
e &
Password’
TC_IN_1 Plan to give 1.Run Usernam Sign Up Same as PAS ---
username the e : Raja Successful expected S
as Progra Password result
Characters m : 1234
& Password 2.Input
as Integers value of
Userna
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_2 Plan to give 1.Run Usernam Sign Up Same as PAS
username as the e : Successful expected S
Strings & Progra Bha146 result ---
Password m Password
as 2.Input : METOO
Character value of
Userna
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_3 Plan to give 1.Run Usernam Error due to No FAIL
username as the e : special Output
Special Progra (@@$$) character
Characters m Password usage in Minor
& Password 2.Input : Hari987 Username
as String value of
Userna
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_4 Plan to 1.Run Usernam Sign Up Same as PAS
give the e : 8970 Successful expected S
username Progra Password result ---
as Integers m : #!(%%)
& 2.Input
Password value of
Userna
as Special
me &
Characters
Passwor
d in
Signup
Dialogu
e Box
TC_IN_5 Plan to 1.Run Usernam Sign Up Error FAIL
give the e : Surya Successful
username Progra Password
as String m : Sai Major
& 2.Input
Password value of
Userna
as String
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_6 Plan to 1.Run Usernam Error Message No Result FAIL Minor
give the e : Sj364 after
username Progra Password execution
as Strings m :
& 2.Input HASK*(JS
Password value of KD124GJ
Userna DHk(*&(
as
me &
Strin
Passwor
gs with
d in
Extreme
Signup
length
Dialogu
e Box
TC_IN_7 Plan to 1.Run Usernam Error Message Blank Box FAIL
give the e : JAI
username
as Strings
&
Password Progra Password Medi
as NULL m : um
2.Input
value of
Userna
me &
Passwor
d in
Signup
Dialogu
e Box
TC_IN_8 Plan to 1.Run Usernam Error Message Username PAS
give the e: cannot S
username Progra Password be ---
as NULL m : Krish12 Empty
& 2.Input
Password value of
Userna
as String
me &
Passwor
d in
Signup
Dialogu
e Box
Client/Server protocol:
CONNECTED – Connection is established.
REGOK – Registration is ok.
REGREF – Registration is refused.
LOGINOK – Login is ok.
LOGINREF – Login is refused.
PING – Server to the client, keeping connection alive.
PONG – Client response to ping, only after ping.
NOCONN – Can not connect for some reason.
USERS <user1 user2 .. usern> - Users online.
ADDUSER <user> - A new user is online.
CHAT <txt> - Text transfer/chat.
REMOVEUSER <user> - A user has logged off.
CLOSECHAT – A user has closed the chat.
SOURCE CODE:
Socketclient.java
package com.socket;
import com.ui.ChatFrame;
import java.io.*;
import java.net.*;
import java.util.Date;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
@Override
public void run() {
boolean keepRunning = true;
while(keepRunning){
try {
Message msg = (Message) In.readObject();
System.out.println("Incoming : "+msg.toString());
if(msg.type.equals("message")){
if(msg.recipient.equals(ui.username)){
ui.jTextArea1.append("["+msg.sender +" > Me] : " + msg.content
+ "\n");
}
else{
ui.jTextArea1.append("[Me > "+ msg.recipient +"] : " +
msg.content + "\n");
}
if(!msg.content.equals(".bye") &&
!msg.sender.equals(ui.username)){
String msgTime = (new Date()).toString();
}
}
else if(msg.type.equals("login")){
if(msg.content.equals("TRUE")){
ui.jButton2.setEnabled(false); ui.jButton3.setEnabled(false);
ui.jButton4.setEnabled(true); ui.jButton5.setEnabled(true);
ui.jTextArea1.append("[SERVER > Me] : Login Successful\n");
ui.jTextField3.setEnabled(false);
ui.jPasswordField1.setEnabled(false);
}
else{
ui.jTextArea1.append("[SERVER > Me] : Login Failed\n");
}
}
else if(msg.type.equals("test")){
ui.jButton1.setEnabled(false);
ui.jButton2.setEnabled(true); ui.jButton3.setEnabled(true);
ui.jTextField3.setEnabled(true);
ui.jPasswordField1.setEnabled(true);
ui.jTextField1.setEditable(false); ui.jTextField2.setEditable(false);
}
else if(msg.type.equals("newuser")){
if(!msg.content.equals(ui.username)){
boolean exists = false;
for(int i = 0; i < ui.model.getSize(); i++){
if(ui.model.getElementAt(i).equals(msg.content)){
exists = true; break;
}
}
if(!exists){ ui.model.addElement(msg.content); }
}
}
else if(msg.type.equals("signup")){
if(msg.content.equals("TRUE")){
ui.jButton2.setEnabled(false); ui.jButton3.setEnabled(false);
ui.jButton4.setEnabled(true); ui.jButton5.setEnabled(true);
ui.jTextArea1.append("[SERVER > Me] : Singup Successful\n");
}
else{
ui.jTextArea1.append("[SERVER > Me] : Signup Failed\n");
}
}
else if(msg.type.equals("signout")){
if(msg.content.equals(ui.username)){
ui.jTextArea1.append("["+ msg.sender +" > Me] : Bye\n");
ui.jButton1.setEnabled(true); ui.jButton4.setEnabled(false);
ui.jTextField1.setEditable(true); ui.jTextField2.setEditable(true);
ui.clientThread.stop();
}
else{
ui.model.removeElement(msg.content);
ui.jTextArea1.append("["+ msg.sender +" > All] : "+ msg.content
+" has signed out\n");
}
}
else if(msg.type.equals("upload_req")){
ui.jButton5.setEnabled(false); ui.jButton6.setEnabled(false);
Upload upl = new Upload(addr, port, ui.file, ui);
Thread t = new Thread(upl);
t.start();
}
else{
ui.jTextArea1.append("[SERVER > Me] : "+msg.sender+"
rejected file request\n");
}
}
else{
ui.jTextArea1.append("[SERVER > Me] : Unknown message
type\n");
}
}
catch(Exception ex) {
keepRunning = false;
ui.jTextArea1.append("[Application > Me] : Connection Failure\n");
ui.jButton1.setEnabled(true); ui.jTextField1.setEditable(true);
ui.jTextField2.setEditable(true);
ui.jButton4.setEnabled(false); ui.jButton5.setEnabled(false);
ui.jButton5.setEnabled(false);
ui.clientThread.stop();
}
}
catch (IOException ex) {
System.out.println("Exception SocketClient send()");
}
}
public void closeThread(Thread t){
t = null;
}
}
Upload.java:
package com.socket;
import com.ui.ChatFrame;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
Message.java:
package com.socket;
import java.io.Serializable;
@Override
public String toString(){
return "{type='"+type+"', sender='"+sender+"', content='"+content+"',
recipient='"+recipient+"'}";
}
}
Download.java:
package com.socket;
import com.ui.ChatFrame;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
@Override
public void run() {
try {
socket = server.accept();
System.out.println("Download : "+socket.getRemoteSocketAddress());
In = socket.getInputStream();
Out = new FileOutputStream(saveTo);
Out.flush();
SERVER SIDE:
Message.java
package com.socket;
import java.io.Serializable;
@Override
public String toString(){
return "{type='"+type+"', sender='"+sender+"', content='"+content+"',
recipient='"+recipient+"'}";
}
}
Database.java:
package com.socket;
import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
try{
File fXmlFile = new File(filePath);
DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
try{
File fXmlFile = new File(filePath);
DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
try {
DocumentBuilderFactory docFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filePath);
newuser.appendChild(newusername);
newuser.appendChild(newpassword); data.appendChild(newuser);
TransformerFactory transformerFactory =
TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filePath));
transformer.transform(source, result);
}
catch(Exception ex){
System.out.println("Exceptionmodify xml");
}
}
SCREENSHOTS:
Messenger Home
Server home:
Connected to a database:
Screen Home:
5 Conclusion:
I have created a client, a server, an administrator and set up a database. The
applications are done, except for the administrator, which needs more work. The
standard functionality of the server is in place; users can register, log in, chat
with other users, IP addresses can be banned through the database. To sum it up:
Client – Done
Server – Done
Administrator – Needs more work
Database – Done
6 Future work:
I will continue to work on this project. The most obvious future work will be:
Finishing the administrator.
Polish the GUI of the applications.
Fix bugs and errors.
7 References
Source 1: “Java Technology”, http://java.sun.com/
Source 2: “MySQL. The world’s most popular open source
database”, http://www.mysql.com/