Objective
In this topic, we will develop a login application based on Client-Server model with TCP/IP protocol. The program is constructed on the MVC model for both client and server sides.
The application will be organized as follow:
- At the server side, the server manages a database which contains a table containing the user data, including username and password for each one
- the server does not need a graphical interface, so we could use console interface for it
- At the client side, the client have to provide a graphical interface which enables user to enter his username/password to login
Class diagrams
At the client side, there are three classes:
- User: this is an model class which contains at least two attributes: username, and password. This class is commonly used on both client and server side.
- ClientView: a graphical view class enabling user to enter username/password to login and then, displaying the results of login to the user
- ClientControl: a control class which gets username/password form view class and send them to server to check whether it is correct, and then receives the results from the server to send to view class to display.
At the server side, as we could commonly use model class (User) with client side, there are only two classes:
- ServerView: a text (console) simple view class to display the real status of server
- ServerControl: a control class which listens the data going from client side, check it when received to see whether it is correct and then, return the results to the corresponding client.
The sequence of activities is represented as following sequence diagram:
1: an user (actor) enters his username and password on the ClientView interface
2: ClientView packs these two attributes into an object of User class
3: ClientView sends this object to ClientControl
4: ClientControl sends this object to ServerControl via TCP/IP protocol
5: ServerControl checks the login data
6: ServerControl returns the results to ClientControl
7: ClientControl sends these results to ClientView
8: ClientView displays the login result to the user
User.java
package tcp.client;
import java.io.Serializable;
public class User implements Serializable{
private String userName;
private String password;
public User(){
}
public User(String username, String password){
this.userName = username;
this.password = password;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
ClientView.java
package tcp.client;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class ClientView extends JFrame implements ActionListener{
private JTextField txtUsername;
private JPasswordField txtPassword;
private JButton btnLogin;
public ClientView(){
super("TCP Login MVC");
txtUsername = new JTextField(15);
txtPassword = new JPasswordField(15);
txtPassword.setEchoChar('*');
btnLogin = new JButton("Login");
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(new JLabel("Username:"));
content.add(txtUsername);
content.add(new JLabel("Password:"));
content.add(txtPassword);
content.add(btnLogin);
this.setContentPane(content);
this.pack();
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
public User getUser(){
User model = new User(txtUsername.getText(), txtPassword.getText());
return model;
}
public void showMessage(String msg){
JOptionPane.showMessageDialog(this, msg);
}
public void addLoginListener(ActionListener log) {
btnLogin.addActionListener(log);
}
}
ClientControl.java
package tcp.client;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class ClientControl {
private ClientView view;
private String serverHost = "localhost";
private int serverPort = 8888;
public ClientControl(ClientView view){
this.view = view;
this.view.addLoginListener(new LoginListener());
}
class LoginListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
User user = view.getUser();
Socket mySocket = new Socket(serverHost, serverPort);
ObjectOutputStream oos = new ObjectOutputStream(mySocket.getOutputStream());
oos.writeObject(user);
ObjectInputStream ois = new ObjectInputStream(mySocket.getInputStream());
Object o = ois.readObject();
if(o instanceof String){
String result = (String)o;
if(result.equals("ok")) view.showMessage("Login succesfully!");
else view.showMessage("Invalid username and/or password!");
}
mySocket.close();
} catch (Exception ex) {
view.showMessage(ex.getStackTrace().toString());
}
}
}
public static void main(String[] args) {
ClientView view = new ClientView();
ClientControl control = new ClientControl(view);
view.setVisible(true);
}
}
ServerView.java
package tcp.server;
public class ServerView {
public ServerView(){
}
public void showMessage(String msg){
System.out.println(msg);
}
}
ServerControl.java
package tcp.server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import tcp.client.User;
public class ServerControl {
private ServerView view;
private Connection con;
private ServerSocket myServer;
private Socket clientSocket;
private int serverPort = 8888;
public ServerControl(ServerView view){
this.view = view;
getDBConnection("loginDB", "root", "123456");
openServer(serverPort);
view.showMessage("TCP server is running...");
while(true){
listenning();
}
}
private void getDBConnection(String dbName, String username, String password){
String dbUrl = "jdbc:mysql://your.database.domain/" + dbName;
String dbClass = "com.mysql.jdbc.Driver";
try {
Class.forName(dbClass);
con = DriverManager.getConnection (dbUrl, username, password);
}catch(Exception e) {
view.showMessage(e.getStackTrace().toString());
}
}
private void openServer(int portNumber){
try {
myServer = new ServerSocket(portNumber);
}catch(IOException e) {
view.showMessage(e.toString());
}
}
private void listenning(){
try {
clientSocket = myServer.accept();
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
Object o = ois.readObject();
if(o instanceof User){
User user = (User)o;
if(checkUser(user)){
oos.writeObject("ok");
}
else
oos.writeObject("false");
}
}catch (Exception e) {
view.showMessage(e.toString());
}
}
private boolean checkUser(User user) throws Exception {
String query = "Select * FROM users WHERE username ='" + user.getUserName()
+ "' AND password ='" + user.getPassword() + "'";
try {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
if (rs.next()) {
return true;
}
}catch(Exception e) {
throw e;
} return false;
}
public static void main(String[] args) {
ServerView view = new ServerView();
ServerControl control = new ServerControl(view);
}
}
Deploying
- Create a database named "LoginDB" in a DBMS at the server side, in which, create a table containing two columns: username, password
- run the ServerControl first
- then run the ClientControl.
No comments:
Post a Comment