Objective
In this topic, we will develop a login application based on Client-Server model with UDP 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 customer data
– The server has a graphical interface to manipulate the server socket such as start, stop, and show the connections from clients.
– At the client side, There are graphical interfaces: one is the main interface to manipulate the connection to the server: connect, disconnect, choose the function… Other enables user to search and edit information of a customer.
Class diagrams
At the third side, there are entity classes (They could be implemented in a separated project and then, exported to a .jar file to be imported into the client project and the server project):
- Customer: this is an model class containing all necessary customer attributes. This class is commonly used on both client and server side.
- ObjectWrapper: this is a kind of exchange data between client-server. This wraps an entity and a performative which indicates the requirement type from client or the result type from the server to distinguish the current service/function on each connection.
- IPAddress: the entity containing the information about the host and the port of a server
At the client side, there are following classes (some relationship among classes are omitted, these classes could also be implemented in a separated UDP client project) ):
- ClientMainFrm: the main client interface to manipulate the connection to the server: connect, disconnect, choose the function…
- SearchCustomerFrm: a graphical view class enabling user to search and choose the customer to update.
- EditCustomerFrm: the form to edit information of the chosen customer
- ClientCtr: a control class to exchange the data to/from server side.

At the server side, there are some other classes (these classes could also be implemented in a separated UDP server project) :
- At the DAO level, there are two classes of DAO and CustomerDAO which has two method: searchCustomer() to search all customer whose name contains the input string, and editCustomer() to update the data of the given input customer.
- At the business control level, there are also three classes:
- ServerCtr to manage the server socket. This will create a UDPListening thread inside its constructor.
- UDPListening is a Thread inherited class to listening the data sent from client. In this processing thread, we have to be based on the performative of the incoming message to call the respective function from the DAO level. The performative value is defined as some constant in the ObjectWrapper class (see in the code at the bottom).
- At the view level, there is the ServerMainFrm to manipulate the server datagram socket: open, close, and display information a bout it.
The sequence of activities is represented as following sequence diagram:
- Step 1-9 : the server opens server datagram socket at the server side
- Step 10-15: a client opens its own datagram socket receive data from the server.
- Step 16-43: client user choose the search customer by name (16-20), the client wraps the keyword into an wrapper object (23-25) and then, send the keyword to server (26-29), the server searches in the DB (32-37), wraps the results (38-40) and return the results to the client (41), the client receives and show it to the user (30-31, 42-43).
- Step 44-71: client user choose a customer to update (44-49), the client wraps (51-56) and then, send the modified object to server (57-60), the server updates it into the DB (63-65) and then, wraps (66-68) and return the results to the client (69). The client receives and show the success message to the user (61-62, 70-71).

Complete code
Class: Customer.java
package model;
import java.io.Serializable;
public class Customer implements Serializable{
private static final long serialVersionUID = 20210811004L;
private int id;
private String name;
private String idCard;
private String address;
private String tel;
private String email;
private String note;
public Customer() {
super();
}
public Customer(String name, String idCard, String address, String tel, String email, String note) {
super();
this.name = name;
this.idCard = idCard;
this.address = address;
this.tel = tel;
this.email = email;
this.note = note;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
Class: ObjectWrapper.java
package model;
import java.io.Serializable;
public class ObjectWrapper implements Serializable{
private static final long serialVersionUID = 20210811011L;
public static final int LOGIN_USER = 1;
public static final int REPLY_LOGIN_USER = 2;
public static final int EDIT_CUSTOMER = 3;
public static final int REPLY_EDIT_CUSTOMER = 4;
public static final int SEARCH_CUSTOMER_BY_NAME = 5;
public static final int REPLY_SEARCH_CUSTOMER = 6;
public static final int SERVER_INFORM_CLIENT_NUMBER = 7;
private int performative;
private Object data;
public ObjectWrapper() {
super();
}
public ObjectWrapper(int performative, Object data) {
super();
this.performative = performative;
this.data = data;
}
public int getPerformative() {
return performative;
}
public void setPerformative(int performative) {
this.performative = performative;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
Class: IPAddress.java
package model;
import java.io.Serializable;
public class IPAddress implements Serializable{
private static final long serialVersionUID = 20210811012L;
private String host;
private int port;
public IPAddress() {
super();
}
public IPAddress(String host, int port) {
super();
this.host = host;
this.port = port;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
ClientMainFrm.java
package udp.client.view;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
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.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import model.IPAddress;
import udp.client.control.ClientCtr;
public class ClientMainFrm extends JFrame implements ActionListener{
private JMenuBar mnbMain;
private JMenu mnUser, mnClient;
private JMenuItem mniLogin, mniEditClient;
private JTextField txtServerHost, txtServerPort, txtClientHost, txtClientPort;
private JButton btnStart, btnStop;
private JTextArea mainText;
private ClientCtr myControl;
public ClientMainFrm(){
super("UDP client view");
JPanel mainPanel = new JPanel();
mainPanel.setLayout(null);
mnbMain = new JMenuBar();
mnUser = new JMenu("User");
mniLogin = new JMenuItem("Login");
mniLogin.addActionListener(this);
mnUser.add(mniLogin);
mnbMain.add(mnUser);
mnClient = new JMenu("Customer");
mniEditClient = new JMenuItem("Edit customer");
mniEditClient.addActionListener(this);
mnClient.add(mniEditClient);
mnbMain.add(mnClient);
this.setJMenuBar(mnbMain);
mniLogin.setEnabled(false);
mniEditClient.setEnabled(false);
JLabel lblTitle = new JLabel("Client UDP");
lblTitle.setFont(new java.awt.Font("Dialog", 1, 20));
lblTitle.setBounds(new Rectangle(150, 20, 200, 30));
mainPanel.add(lblTitle, null);
JLabel lblHost = new JLabel("Server host:");
lblHost.setBounds(new Rectangle(10, 70, 150, 25));
mainPanel.add(lblHost, null);
txtServerHost = new JTextField(50);
txtServerHost.setBounds(new Rectangle(100, 70, 150, 25));
mainPanel.add(txtServerHost,null);
JLabel lblPort = new JLabel("Server port:");
lblPort.setBounds(new Rectangle(10, 100, 150, 25));
mainPanel.add(lblPort, null);
txtServerPort = new JTextField(50);
txtServerPort.setBounds(new Rectangle(100, 100, 150, 25));
mainPanel.add(txtServerPort,null);
JLabel lblClientHost = new JLabel("This client host:");
lblClientHost.setBounds(new Rectangle(300, 70, 150, 25));
mainPanel.add(lblClientHost, null);
txtClientHost = new JTextField(50);
txtClientHost.setText("localhost");
txtClientHost.setBounds(new Rectangle(420, 70, 150, 25));
txtClientHost.setEditable(false);
mainPanel.add(txtClientHost,null);
JLabel lblClientPort = new JLabel("This client port:");
lblClientPort.setBounds(new Rectangle(300, 100, 150, 25));
mainPanel.add(lblClientPort, null);
txtClientPort = new JTextField(50);
txtClientPort.setBounds(new Rectangle(420, 100, 150, 25));
mainPanel.add(txtClientPort,null);
btnStart = new JButton("Start");
btnStart.setBounds(new Rectangle(10, 150, 150, 25));
btnStart.addActionListener(this);
mainPanel.add(btnStart,null);
btnStop = new JButton("Stop");
btnStop.setBounds(new Rectangle(170, 150, 150, 25));
btnStop.addActionListener(this);
btnStop.setEnabled(false);
mainPanel.add(btnStop,null);
JScrollPane jScrollPane1 = new JScrollPane();
mainText = new JTextArea("");
jScrollPane1.setBounds(new Rectangle(10, 200, 610, 240));
mainPanel.add(jScrollPane1, BorderLayout.CENTER);
jScrollPane1.getViewport().add(mainText, null);
this.setContentPane(mainPanel);
this.pack();
this.setSize(new Dimension(640, 480));
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
this.addWindowListener( new WindowAdapter(){
public void windowClosing(WindowEvent e) {
if(myControl != null) {
myControl.close();
}
System.exit(0);
}
});
}
@Override
public void actionPerformed(ActionEvent ae) {
// TODO Auto-generated method stub
if(ae.getSource() instanceof JButton) {
JButton btn = (JButton)ae.getSource();
if(btn.equals(btnStart)) {// connect button
if(!txtServerHost.getText().isEmpty() && (txtServerHost.getText().trim().length() > 0) &&
!txtServerPort.getText().isEmpty() && (txtServerPort.getText().trim().length() > 0)) {//custom server port
int serverPort = Integer.parseInt(txtServerPort.getText().trim());
if(!txtClientPort.getText().isEmpty() && (txtClientPort.getText().trim().length() > 0)) {//custom client port
int clientPort = Integer.parseInt(txtClientPort.getText().trim());
myControl = new ClientCtr(this, new IPAddress(txtServerHost.getText().trim(), serverPort), clientPort);
}else {//default client port
myControl = new ClientCtr(this, new IPAddress(txtServerHost.getText().trim(), serverPort));
}
}else {//default server host and port
if(!txtClientPort.getText().isEmpty() && (txtClientPort.getText().trim().length() > 0)) {//custom client port
int clientPort = Integer.parseInt(txtClientPort.getText().trim());
myControl = new ClientCtr(this, clientPort);
}else {//default client port
myControl = new ClientCtr(this);
}
}
if(myControl.open()) {
btnStop.setEnabled(true);
btnStart.setEnabled(false);
mniLogin.setEnabled(true);
mniEditClient.setEnabled(true);
}else {
if(myControl != null) {
myControl.close();
myControl = null;
}
btnStop.setEnabled(false);
btnStart.setEnabled(true);
mniLogin.setEnabled(false);
mniEditClient.setEnabled(false);
}
}else if(btn.equals(btnStop)) {// disconnect button
if(myControl != null) {
myControl.close();
myControl = null;
}
btnStop.setEnabled(false);
btnStart.setEnabled(true);
mniLogin.setEnabled(false);
mniEditClient.setEnabled(false);
}
}else if(ae.getSource() instanceof JMenuItem) {
JMenuItem mni = (JMenuItem)ae.getSource();
if(mni.equals(mniLogin)) {// login function
}else if(mni.equals(mniEditClient)) {// Search client to edit
SearchCustomerFrm scv = new SearchCustomerFrm(myControl);
scv.setVisible(true);
}
}
}
public void showMessage(String s){
mainText.append("\n"+s);
mainText.setCaretPosition(mainText.getDocument().getLength());
}
public void setServerandClientInfo(IPAddress serverAddress, IPAddress clientAddress) {
txtServerHost.setText(serverAddress.getHost());
txtServerPort.setText(serverAddress.getPort()+"");
txtClientHost.setText(clientAddress.getHost());
txtClientPort.setText(clientAddress.getPort()+"");
}
public static void main(String[] args) {
ClientMainFrm view = new ClientMainFrm();
view.setVisible(true);
}
}
SearchCustomerFrm.java
package udp.client.view;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import model.Customer;
import model.ObjectWrapper;
import udp.client.control.ClientCtr;
public class SearchCustomerFrm extends JFrame implements ActionListener{
private ArrayList<Customer> listCustomer;
private JTextField txtKey;
private JButton btnSearch;
private JTable tblResult;
private ClientCtr mySocket;
public SearchCustomerFrm(ClientCtr socket){
super("Search customer to edit");
mySocket = socket;
listCustomer = new ArrayList<Customer>();
JPanel pnMain = new JPanel();
pnMain.setSize(this.getSize().width-5, this.getSize().height-20);
pnMain.setLayout(new BoxLayout(pnMain,BoxLayout.Y_AXIS));
pnMain.add(Box.createRigidArea(new Dimension(0,10)));
JLabel lblHome = new JLabel("Search a customer to edit");
lblHome.setAlignmentX(Component.CENTER_ALIGNMENT);
lblHome.setFont (lblHome.getFont ().deriveFont (20.0f));
pnMain.add(lblHome);
pnMain.add(Box.createRigidArea(new Dimension(0,20)));
JPanel pn1 = new JPanel();
pn1.setLayout(new BoxLayout(pn1,BoxLayout.X_AXIS));
pn1.setSize(this.getSize().width-5, 20);
pn1.add(new JLabel("Client name: "));
txtKey = new JTextField();
pn1.add(txtKey);
btnSearch = new JButton("Search");
btnSearch.addActionListener(this);
pn1.add(btnSearch);
pnMain.add(pn1);
pnMain.add(Box.createRigidArea(new Dimension(0,10)));
JPanel pn2 = new JPanel();
pn2.setLayout(new BoxLayout(pn2,BoxLayout.Y_AXIS));
tblResult = new JTable();
JScrollPane scrollPane= new JScrollPane(tblResult);
tblResult.setFillsViewportHeight(false);
scrollPane.setPreferredSize(new Dimension(scrollPane.getPreferredSize().width, 250));
tblResult.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
int column = tblResult.getColumnModel().getColumnIndexAtX(e.getX()); // get the coloum of the button
int row = e.getY() / tblResult.getRowHeight(); // get the row of the button
// *Checking the row or column is valid or not
if (row < tblResult.getRowCount() && row >= 0 && column < tblResult.getColumnCount() && column >= 0) {
(new EditCustomerFrm(mySocket, listCustomer.get(row))).setVisible(true);
dispose();
}
}
});
pn2.add(scrollPane);
pnMain.add(pn2);
this.add(pnMain);
this.setSize(600,300);
this.setLocation(200,10);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JButton btnClicked = (JButton)e.getSource();
if(btnClicked.equals(btnSearch)){
if((txtKey.getText() == null)||(txtKey.getText().length() == 0))
return;
//send data to the server
mySocket.sendData(new ObjectWrapper(ObjectWrapper.SEARCH_CUSTOMER_BY_NAME, txtKey.getText().trim()));
//receive result from the server
ObjectWrapper data = mySocket.receiveData();
if(data.getPerformative() == ObjectWrapper.REPLY_SEARCH_CUSTOMER) {
listCustomer = (ArrayList<Customer>)data.getData();
String[] columnNames = {"Id", "Name", "idCard", "Address", "Email", "Tel", "Note"};
String[][] value = new String[listCustomer.size()][columnNames.length];
for(int i=0; i<listCustomer.size(); i++){
value[i][0] = listCustomer.get(i).getId() +"";
value[i][1] = listCustomer.get(i).getName();
value[i][2] = listCustomer.get(i).getIdCard();
value[i][3] = listCustomer.get(i).getAddress();
value[i][4] = listCustomer.get(i).getEmail();
value[i][5] = listCustomer.get(i).getTel();
value[i][6] = listCustomer.get(i).getNote();
}
DefaultTableModel tableModel = new DefaultTableModel(value, columnNames) {
@Override
public boolean isCellEditable(int row, int column) {
//unable to edit cells
return false;
}
};
tblResult.setModel(tableModel);
}else {
tblResult.setModel(null);
}
}
}
}
EditCustomerFrm.java
package udp.client.view;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import model.Customer;
import model.ObjectWrapper;
import udp.client.control.ClientCtr;
public class EditCustomerFrm extends JFrame implements ActionListener{
private Customer customer;
private JTextField txtId, txtName, txtIdcard, txtAddress, txtEmail, txtTel, txtNote;
private JButton btnUpdate, btnReset;
private ClientCtr mySocket;
public EditCustomerFrm(ClientCtr socket, Customer client){
super("Edit a customer");
mySocket = socket;
this.customer = client;
JPanel pnMain = new JPanel();
pnMain.setSize(this.getSize().width-5, this.getSize().height-20);
pnMain.setLayout(new BoxLayout(pnMain,BoxLayout.Y_AXIS));
pnMain.add(Box.createRigidArea(new Dimension(0,10)));
JLabel lblHome = new JLabel("Edit a customer information");
lblHome.setAlignmentX(Component.CENTER_ALIGNMENT);
lblHome.setFont (lblHome.getFont ().deriveFont (20.0f));
pnMain.add(lblHome);
pnMain.add(Box.createRigidArea(new Dimension(0,20)));
txtId = new JTextField(15);
txtId.setEditable(false);
txtName = new JTextField(15);
txtIdcard = new JTextField(15);
txtAddress = new JTextField(15);
txtEmail = new JTextField(15);
txtTel = new JTextField(15);
txtNote = new JTextField(15);
btnUpdate = new JButton("Update");
btnReset = new JButton("Reset");
JPanel content = new JPanel();
content.setLayout(new GridLayout(8,2));
content.add(new JLabel("Customer ID:")); content.add(txtId);
content.add(new JLabel("Name:")); content.add(txtName);
content.add(new JLabel("Idcard:")); content.add(txtIdcard);
content.add(new JLabel("Address:")); content.add(txtAddress);
content.add(new JLabel("Email:")); content.add(txtEmail);
content.add(new JLabel("Tel:")); content.add(txtTel);
content.add(new JLabel("Note:")); content.add(txtNote);
content.add(btnUpdate); content.add(btnReset);
pnMain.add(content);
btnUpdate.addActionListener(this);
btnReset.addActionListener(this);
initForm();
this.setContentPane(pnMain);
this.setSize(600,300);
this.setLocation(200,10);
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
private void initForm(){
if(customer != null){
txtId.setText(customer.getId()+"");
txtName.setText(customer.getName());
txtIdcard.setText(customer.getIdCard());
txtAddress.setText(customer.getAddress());
txtEmail.setText(customer.getEmail());
txtTel.setText(customer.getTel());
txtNote.setText(customer.getNote());
}
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JButton btnClicked = (JButton)e.getSource();
if(btnClicked.equals(btnReset)){
initForm();
return;
}
if(btnClicked.equals(btnUpdate)){
customer.setName(txtName.getText());
customer.setIdCard(txtIdcard.getText());
customer.setAddress(txtAddress.getText());
customer.setEmail(txtEmail.getText());
customer.setTel(txtTel.getText());
customer.setNote(txtNote.getText());
//send data to the server
mySocket.sendData(new ObjectWrapper(ObjectWrapper.EDIT_CUSTOMER, customer));
//receive result from the server
ObjectWrapper data = mySocket.receiveData();
if(data.getPerformative() == ObjectWrapper.REPLY_EDIT_CUSTOMER) {
String result = (String)data.getData();
if(result.equals("ok")) {
JOptionPane.showMessageDialog(this, "Update succesfully!");
this.dispose();
}
else {
JOptionPane.showMessageDialog(this, "Error when updating!");
}
}
}
}
}
ClientCtr.java
package udp.client.control;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import model.IPAddress;
import model.ObjectWrapper;
import udp.client.view.ClientMainFrm;
public class ClientCtr {
private ClientMainFrm view;
private DatagramSocket myClient;
private IPAddress serverAddress = new IPAddress("localhost", 5555); //default server address
private IPAddress myAddress = new IPAddress("localhost", 6666); //default client address
public ClientCtr(ClientMainFrm view){
this.view = view;
}
public ClientCtr(ClientMainFrm view, int clientPort){
this.view = view;
myAddress.setPort(clientPort);
}
public ClientCtr(ClientMainFrm view, IPAddress serverAddr){
this.view = view;
serverAddress = serverAddr;
}
public ClientCtr(ClientMainFrm view, IPAddress serverAddr, int clientPort){
this.view = view;
serverAddress = serverAddr;
myAddress.setPort(clientPort);
}
public boolean open(){
try {
myClient = new DatagramSocket(myAddress.getPort());
myAddress.setHost(InetAddress.getLocalHost().getHostAddress());
view.setServerandClientInfo(serverAddress, myAddress);
view.showMessage("UDP client is running at the host: " + myAddress.getHost() + ", port: " + myAddress.getPort());
}catch(Exception e) {
e.printStackTrace();
view.showMessage("Error to open the datagram socket!");
return false;
}
return true;
}
public boolean close(){
try {
myClient.close();
}catch(Exception e) {
e.printStackTrace();
view.showMessage("Error to close the datagram socket!");
return false;
}
return true;
}
public boolean sendData(ObjectWrapper data){
try {
//prepare the buffer and write the data to send into the buffer
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(data);
oos.flush();
//create data package and send
byte[] sendData = baos.toByteArray();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName(serverAddress.getHost()), serverAddress.getPort());
myClient.send(sendPacket);
} catch (Exception e) {
e.printStackTrace();
view.showMessage("Error in sending data package");
return false;
}
return true;
}
public ObjectWrapper receiveData(){
ObjectWrapper result = null;
try {
//prepare the buffer and fetch the received data into the buffer
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
myClient.receive(receivePacket);
//read incoming data from the buffer
ByteArrayInputStream bais = new ByteArrayInputStream(receiveData);
ObjectInputStream ois = new ObjectInputStream(bais);
result = (ObjectWrapper)ois.readObject();
} catch (Exception e) {
e.printStackTrace();
view.showMessage("Error in receiving data package");
}
return result;
}
}
ServerMainFrm.java
package udp.server.view;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import model.IPAddress;
import udp.server.control.ServerCtr;
public class ServerMainFrm extends JFrame implements ActionListener{
private JTextField txtServerHost;
private JTextField txtServerPort;
private JButton btnStartServer;
private JButton btnStopServer;
private JTextArea mainText;
private ServerCtr myServer;
public ServerMainFrm(){
super("UDP server view");
JPanel mainPanel = new JPanel();
mainPanel.setLayout(null);
JLabel lblTitle = new JLabel("Server UDP");
lblTitle.setFont(new java.awt.Font("Dialog", 1, 20));
lblTitle.setBounds(new Rectangle(150, 15, 200, 30));
mainPanel.add(lblTitle, null);
JLabel lblHost = new JLabel("Server host:");
lblHost.setBounds(new Rectangle(10, 70, 150, 25));
mainPanel.add(lblHost, null);
txtServerHost = new JTextField(50);
txtServerHost.setBounds(new Rectangle(170, 70, 150, 25));
txtServerHost.setText("localhost");
txtServerHost.setEditable(false);
mainPanel.add(txtServerHost,null);
JLabel lblPort = new JLabel("Server port:");
lblPort.setBounds(new Rectangle(10, 100, 150, 25));
mainPanel.add(lblPort, null);
txtServerPort = new JTextField(50);
txtServerPort.setBounds(new Rectangle(170, 100, 150, 25));
mainPanel.add(txtServerPort,null);
btnStartServer = new JButton("Start server");
btnStartServer.setBounds(new Rectangle(10, 150, 150, 25));
btnStartServer.addActionListener(this);
mainPanel.add(btnStartServer,null);
btnStopServer = new JButton("Stop server");
btnStopServer.setBounds(new Rectangle(170, 150, 150, 25));
btnStopServer.addActionListener(this);
btnStopServer.setEnabled(false);
mainPanel.add(btnStopServer,null);
JScrollPane jScrollPane1 = new JScrollPane();
mainText = new JTextArea("");
jScrollPane1.setBounds(new Rectangle(10, 200, 610, 240));
mainPanel.add(jScrollPane1, BorderLayout.CENTER);
jScrollPane1.getViewport().add(mainText, null);
this.setContentPane(mainPanel);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(new Dimension(640, 480));
this.setResizable(false);
}
public void showServerInfo(IPAddress serverAddr) {
txtServerHost.setText(serverAddr.getHost());
txtServerPort.setText(serverAddr.getPort()+"");
}
@Override
public void actionPerformed(ActionEvent ae) {
// TODO Auto-generated method stub
if(ae.getSource() instanceof JButton) {
JButton clicked = (JButton)ae.getSource();
if(clicked.equals(btnStartServer)) {// start button
if(!txtServerPort.getText().isEmpty() && (txtServerPort.getText().trim().length() > 0)) {//custom port
int port = Integer.parseInt(txtServerPort.getText().trim());
myServer = new ServerCtr(this, port);
}else {// default port
myServer = new ServerCtr(this);
}
if(myServer.open()) {
btnStopServer.setEnabled(true);
btnStartServer.setEnabled(false);
}
}else if(clicked.equals(btnStopServer)) {// stop button
if(myServer != null) {
myServer.close();
myServer = null;
}
btnStopServer.setEnabled(false);
btnStartServer.setEnabled(true);
txtServerHost.setText("localhost");
}
}
}
public void showMessage(String s){
mainText.append("\n"+s);
mainText.setCaretPosition(mainText.getDocument().getLength());
}
public static void main(String[] args) {
ServerMainFrm view = new ServerMainFrm();
view.setVisible(true);
}
}
ServerCtr.java
package udp.server.control;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import jdbc.dao.CustomerDAO;
import jdbc.dao.UserDAO;
import model.Customer;
import model.IPAddress;
import model.ObjectWrapper;
import model.User;
import udp.server.view.ServerMainFrm;
public class ServerCtr {
private ServerMainFrm view;
private DatagramSocket myServer;
private IPAddress myAddress = new IPAddress("localhost", 5555); //default server address
private UDPListening myListening;
public ServerCtr(ServerMainFrm view){
this.view = view;
}
public ServerCtr(ServerMainFrm view, int port){
this.view = view;
myAddress.setPort(port);
}
public boolean open(){
try {
myServer = new DatagramSocket(myAddress.getPort());
myAddress.setHost(InetAddress.getLocalHost().getHostAddress());
view.showServerInfo(myAddress);
myListening = new UDPListening();
myListening.start();
view.showMessage("UDP server is running at the host: " + myAddress.getHost() + ", port: " + myAddress.getPort());
}catch(Exception e) {
e.printStackTrace();
view.showMessage("Error to open the datagram socket!");
return false;
}
return true;
}
public boolean close(){
try {
myListening.stop();
myServer.close();
}catch(Exception e) {
e.printStackTrace();
view.showMessage("Error to close the datagram socket!");
return false;
}
return true;
}
class UDPListening extends Thread{
public UDPListening() {
}
public void run() {
while(true) {
try {
//prepare the buffer and fetch the received data into the buffer
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
myServer.receive(receivePacket);
//read incoming data from the buffer
ByteArrayInputStream bais = new ByteArrayInputStream(receiveData);
ObjectInputStream ois = new ObjectInputStream(bais);
ObjectWrapper receivedData = (ObjectWrapper)ois.readObject();
//processing
ObjectWrapper resultData = new ObjectWrapper();
switch(receivedData.getPerformative()) {
case ObjectWrapper.LOGIN_USER: // login
User user = (User)receivedData.getData();
resultData.setPerformative(ObjectWrapper.REPLY_LOGIN_USER);
if(new UserDAO().checkLogin(user))
resultData.setData("ok");
else
resultData.setData("false");
break;
case ObjectWrapper.SEARCH_CUSTOMER_BY_NAME: // search customer by name
String key = (String)receivedData.getData();
resultData.setPerformative(ObjectWrapper.REPLY_SEARCH_CUSTOMER);
resultData.setData(new CustomerDAO().searchCustomer(key));
break;
case ObjectWrapper.EDIT_CUSTOMER: // edit customer
Customer cus = (Customer)receivedData.getData();
resultData.setPerformative(ObjectWrapper.REPLY_EDIT_CUSTOMER);
if(new CustomerDAO().editCustomer(cus))
resultData.setData("ok");
else
resultData.setData("false");
break;
}
//prepare the buffer and write the data to send into the buffer
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(resultData);
oos.flush();
//create data package and send
byte[] sendData = baos.toByteArray();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, receivePacket.getAddress(), receivePacket.getPort());
myServer.send(sendPacket);
} catch (Exception e) {
e.printStackTrace();
view.showMessage("Error when processing an incoming package");
}
}
}
}
}
Class: DAO.java
package jdbc.dao;
import java.sql.Connection;
import java.sql.DriverManager;
public class DAO {
public static Connection con;
public DAO(){
if(con == null){
String dbUrl = "jdbc:mysql://localhost:3307/hotel?autoReconnect=true&useSSL=false";
String dbClass = "com.mysql.jdbc.Driver";
try {
Class.forName(dbClass);
con = DriverManager.getConnection (dbUrl, "root", "xxx");
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
Class: CustomerDAO.java
package jdbc.dao;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import model.Customer;
public class CustomerDAO extends DAO{
/**
* search all clients in the tblClient whose name contains the @key
* using PreparedStatement - recommended for professional coding
* @param key
* @return list of client whose name contains the @key
*/
public ArrayList<Customer> searchCustomer(String key){
ArrayList<Customer> result = new ArrayList<Customer>();
String sql = "SELECT * FROM tblclient WHERE name LIKE ?";
try{
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, "%" + key + "%");
ResultSet rs = ps.executeQuery();
while(rs.next()){
Customer client = new Customer();
client.setId(rs.getInt("id"));
client.setName(rs.getString("name"));
client.setIdCard(rs.getString("idcard"));
client.setAddress(rs.getString("address"));
client.setTel(rs.getString("tel"));
client.setEmail(rs.getString("email"));
client.setNote(rs.getString("note"));
result.add(client);
}
}catch(Exception e){
e.printStackTrace();
}
return result;
}
/**
* update the @client
* @param client
*/
public boolean editCustomer(Customer client){
String sql = "UPDATE tblclient SET name=?, idcard =?, address=?, tel=?, email=?, note=? WHERE id=?";
try{
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, client.getName());
ps.setString(2, client.getIdCard());
ps.setString(3, client.getAddress());
ps.setString(4, client.getTel());
ps.setString(5, client.getEmail());
ps.setString(6, client.getNote());
ps.setInt(7, client.getId());
ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
return false;
}
return true;
}
}