Tải bản đầy đủ (.docx) (73 trang)

TÀI LIỆU Đồ án Chat ClientServer, Client Server java

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (841.79 KB, 73 trang )

BỘ GIÁO DỤC VÀ ĐÀO TẠO
TRƯỜNG ĐẠI HỌC MỎ - ĐỊA CHẤT HÀ NỘI
KHOA CÔNG NGHỆ THÔNG TIN
Đồ án lập trình mạng
Xây dựng ứng dụng Chat Client – Server
Giảng Viên Hướng Dẫn: Phan Mạnh Tiến
Nhóm: Đỗ Viết Thanh 1121050299
Nguyễn Thị Thanh Huệ 1121050218
Nguyễn Thanh Hương 1121050228
Nguyễn Thế Phong 1121050073
Phạm Văn Thực 1121050103
Lớp: Mạng Máy Tính K56
Hà Nội, Ngày 18 Tháng 5 Năm 2014
Đồ án: ứng dụng chát Client – Server 2 | P a g e
Mục Lục
I. Tổng quan về đề tài
1. Cơ sở lý thuyết
• Giao thức TCP/IP
• Mô hình Client/Server
• Cơ chế Socket trong Java
2. Phân tích và thiết kế hệ thống
2.1 Phân tích yêu cầu bài toán
Yêu cầu bài toán: Xây dựng chương trình Chát theo mô hình Client – Server sử
dụng Java Socket
Phân tích:
 Xây dựng chương trình bên Server
• Tạo một TCP Socket và gắn vào một cổng
• Kết nối Database để lưu trữ dữ liệu người dùng như: username, password
• Xây dựng một chương trình Server đa tuyến (Thread Server) để cho phép
nhiều Client kết nối đến Server
• Luôn luôn chờ và lắng nghe yêu cầu kết nối từ Client


• Chấp nhận kết nối và tạo ra các Thread (Socket) tương ứng
• Truyền nhận thông tin qua các luồng nhận/gửi dữ liệu của socket
• Cập nhật trạng thái đăng nhập, đăng xuất của các Client và gửi về các
Client
• Thiết kế giao diện Server
• Xử lý 1 số công việc khác …
 Xây dựng chương trình bên Client
• Tạo một TCP Socket với địa chỉ IP và số cổng mà chương trình Server
đang chạy
• Thiết lập kết nối và trao đổi với Server: đăng nhập, đăng xuất …;
• Gửi, Nhận thông điệp với tất cả mọi người trong phòng chát
• Chức năng xem lại lịch sử đã chát
• Chức năng upload, Download File
• Thiết kế giao diện Client
2.2 Thiết kế chương trình
2.2.1 Thiết kế giao diện
• Giao diện của Server
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 3 | P a g e
Giao diện của Server hết sức đơn giản. Thiết kế cơ bản gồm nút Start. Phần Port,
select Database đã được mặc định chọn sẵn trong code.
Server cập nhật trạng thái của các Client và in thông tin ngay tại trên Server và đồng
thời gửi xuống cho các Client
Hình 2.1: Server đang hoạt động
• Giao diện bên Client
Giao diện bên Client được tách ra làm 2 form: ChatFram (phần chát chính) và
HistoryFram (nhật ký chát).
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 4 | P a g e
Hình 2.2 Client đã kết nối đến Server

• ChatFram là giao diện tổng hợp của việc kết nối, đăng nhập và Chát.
• Host Address và Port của Server mặc định
• Phần List Online: để hiển thị các nick đang online
• Khung chát chính: tất cả thông báo đến từ Server, chương trình và các tin nhắn
từ thành viên khác đều được hiển thị ở đây
• Gửi tin nhắn: Có thể chát Room qua List Online chọn thuộc tính All. Và chát
riêng khi chọn thành viên muốn chát
• Nhật ký: hiển thị lịch sử đã chát qua 1 form mới là HistoryFram
• Upload File: cho phép gửi tập tin cho người dùng #. Cấm gửi lên cho tất cả
mọi người (tránh tắc nghẽn)
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 5 | P a g e
Hình 2.3 Nhật ký chát
2.2.2 Các lớp xử lý của chương trình
• Phía bên Server
• Phía bên Client
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 6 | P a g e
II. Hướng dẫn cài đặt và chạy Demo chương trình
1. Hướng dẫn cài đặt
Chương trình gồm 2 phần chính là : Client và Server. Muốn chương trình chạy được
thì ta phải chạy Server trước để lắng nghe các Client. Sau đó chạy các Client
Chạy Server ta Run File ServerFrame là Main
Chạy Client ta Run File ChatFramme là Main
2. Chạy Demo Chương trình
Thử nghiệm chạy chương trình lần lượt theo các bước  kết quả được hiển thị
qua các hình
Hình 2.1 Kết nối lỗi khi Server chưa chạy
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 7 | P a g e

Hình 2.2 Chạy chương trình Server
Hính 2.3 Chạy Client Kết nối và đăng nhập thành công
• Sau khi Server đã được bật thì đã kết nối được thành công
• Tiến hành kết nối và đăng nhập thêm nhiều Client khác
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 8 | P a g e
Hình 2.4 Chát Room và chat Private
• Chát Room thì tại List Online ta chọn All và tiến hành chát với mọi người
• Chát Private thì tại List Online ta chọn người muốn chát và tiến hành chát. Như
trong hình thì Đỗ Thanh chát private đến Thanh Huệ. Và Thanh Huệ, Văn
Thực chát Private cho Đỗ Thanh.
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 9 | P a g e
Hình 2.5 Hiển thị nhật ký chát của Thế Phong
Hình 2.6 Thông báo đến các Client khi có Nick đăng xuất
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 10 | P a g e
Hình 2.7 Thông báo trên Server khi có Client thoát, tiến hành giải phóng tài nguyên
và tiếp tục chờ đợi các Client
Hình 2.8 Server gửi thông báo cho Thế Phong không cho phép gửi tập tin cho tất cả
mọi người
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 11 | P a g e
• Tiếp theo sẽ sử dụng kịch bản: Thế Phong gửi File cho Đỗ Thanh. TH1 Đỗ Thanh
từ chối Download, TH2 Đỗ Thanh Download
Hình 2.9 Thông báo khi Thế Phong gửi cho Đỗ Thanh tệp tin.
Hình 2.10 Thông báo Đỗ Thanh không chấp nhận tập tin
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 12 | P a g e
Hình 2.11 Đỗ Thanh chấp nhận Download và thông báo đến 2 người đó

III. Kết Luận và hướng phát triển
1. Những kết quả đạt được
 Mô phỏng thành công mô hình Client – Server trong mạng LAN
 Thực hiện đầy đủ yêu cầu bài ra: Đăng nhập, đăng xuất, List OnLine, Chat
Room, Chat Private.
 Một số chức năng thực hiện thêm: Select Database dạng XML, Nhật ký Chat,
UpLoad File và Download File.
2. Những vấn đề tồn tại
 Chương trình còn đơn giản
 Giao diện sơ sài
3. Hướng phát triển
 Hoàn thiện giao diện đẹp phù hợp với người dùng
 Phát triển trên mạng rộng ngoài mạng LAN
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 13 | P a g e
IV. Source code
1. Chương trình bên Server
1.1Database class
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.*;
public class Database {
public String filePath="";
public Database(String filePath) {

this.filePath = filePath;
}
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 14 | P a g e
public boolean userExists(String username) {
try {
File fXmlFile = new File(filePath);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
// Bình thường hóa văn bản
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("user");
//Duyệt
for (int i = 0; i < nList.getLength(); i++)
{
Node nNode = nList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if (getTagValue("username", eElement).equals(username)) {
return true;
}
}
}
return false;
} catch (Exception ex) {
return false;
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 15 | P a g e
}

}
public boolean checkLogin(String username, String password) {

if (!userExists(username))
{
return false;
}
try {
File fXmlFile = new File(filePath);
DocumentBuilderFactory db = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = db.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("user");
for (int i = 0; i < nList.getLength(); i++)
{
//NodeList ageList = firstPersonElement.getElementsByTagName("age");
//Element ageElement = (Element)ageList.item(0);
//NodeList textAgeList = ageElement.getChildNodes();
//System.out.println("Age : " +
((Node)textAgeList.item(0)).getNodeValue().trim());

Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 16 | P a g e
Node nNode = nList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if (getTagValue("username", eElement).equals(username) &&
getTagValue("password", eElement).equals(password))
{

return true;
}
}
}
System.out.println("Hippie");
return false;
} catch (Exception ex) {
return false;
}
}
public void addUser(String username, String password) {
try {
DocumentBuilderFactory db = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = db.newDocumentBuilder();
Document doc = dBuilder.parse(filePath);
// Tạo 1 node
Node data = doc.getFirstChild();
// Thêm 1 user
Element newuser = doc.createElement("user");
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 17 | P a g e
Element newusername = doc.createElement("username");
newusername.setTextContent(username);
Element newpassword = doc.createElement("password");
newpassword.setTextContent(password);
// Xác nhận
newuser.appendChild(newusername);
newuser.appendChild(newpassword);
data.appendChild(newuser);
//Tạo vào file xml

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) {
}
}
public static String getTagValue(String sTag, Element eElement) {
NodeList nlList =
eElement.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = (Node) nlList.item(0);
return nValue.getNodeValue();
}
}
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 18 | P a g e
1.2 Message class
package com.socket;
import java.io.Serializable;
public class Message implements Serializable{

private static final long serialVersionUID = 1L;
//Loại , người gửi, nội dung, người nhận
public String type, sender, content, recipient;

public Message(String type, String sender, String content, String recipient){
this.type = type; this.sender = sender; this.content = content; this.recipient =
recipient;
}


@Override
public String toString(){
return "{type='"+type+"', sender='"+sender+"', content='"+content+"',
recipient='"+recipient+"'}";
}
}
1.3 ServerFrame class
package com.socket;
import javax.swing.UIManager;
public class ServerFrame extends javax.swing.JFrame {
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 19 | P a g e
public SocketServer server;
public Thread serverThread;
public String filePath = "src\\com\\data\\Data.xml";

public ServerFrame() {
initComponents();
this.setTitle("Server Chat");
txtThongBao.setEditable(false);
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
btnStart = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
txtThongBao = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("jServer");

btnStart.setText("Start Server");
btnStart.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnStartActionPerformed(evt);
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 20 | P a g e
}
});
txtThongBao.setColumns(20);
txtThongBao.setFont(new java.awt.Font("Consolas", 0, 12)); // NOI18N
txtThongBao.setRows(5);
jScrollPane1.setViewportView(txtThongBao);
javax.swing.GroupLayout layout = new
javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE,
561, Short.MAX_VALUE)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addGap(239, 239, 239)
.addComponent(btnStart)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGroup(layout.createSequentialGroup()
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 21 | P a g e
.addGap(16, 16, 16)
.addComponent(btnStart)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE,
287, Short.MAX_VALUE)
.addContainerGap())
);
pack();
}// </editor-fold>
private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {
server = new SocketServer(this);
btnStart.setEnabled(false);
}
public void RetryStart(int port){
if(server != null){ server.stop(); }
server = new SocketServer(this, port);
}

public static void main(String args[]) {
try{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception ex){
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 22 | P a g e
}


java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new ServerFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton btnStart;
private javax.swing.JScrollPane jScrollPane1;
public javax.swing.JTextArea txtThongBao;
// End of variables declaration
}
1.4 SocketServer class
package com.socket;
import java.io.*;
import java.net.*;
class ServerThread extends Thread {
public SocketServer server = null;
public Socket socket = null;
public int ID = -1;
public String username = "";
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 23 | P a g e
public ObjectInputStream In = null;
public ObjectOutputStream Out = null;
public ServerFrame ui;
public ServerThread(SocketServer _server, Socket _socket) {
super();
server = _server;

socket = _socket;
ID = socket.getPort();
ui = _server.ui;
}
public void send(Message msg) {
try {
Out.writeObject(msg);
Out.flush();
} catch (IOException ex) {
}
}
public int getID() {
return ID;
}
@SuppressWarnings("deprecation")
@Override
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 24 | P a g e
public void run() {
ui.txtThongBao.append("\nServer Thread " + ID + " đang chạy ");
while (true) {
try {
Message msg = (Message) In.readObject();
server.handle(ID, msg);
} catch (IOException ioe) {
System.out.println(ID + " Lỗi: " + ioe.getMessage());
server.remove(ID);
} catch (ClassNotFoundException ioe) {
System.out.println(ID + " Lỗi: " + ioe.getMessage());
server.remove(ID);

}
}
}
// Mỗi Thread khởi động ==> không phải viết lại pt Stream
public void open() throws IOException {
Out = new ObjectOutputStream(socket.getOutputStream());
Out.flush();
In = new ObjectInputStream(socket.getInputStream());
}
public void close() throws IOException {
if (socket != null) {
socket.close();
Nhóm 2 – Mạng máy tính K56
Đồ án: ứng dụng chát Client – Server 25 | P a g e
}
if (In != null) {
In.close();
}
if (Out != null) {
Out.close();
}
}
}
public final class SocketServer implements Runnable {
public ServerThread clients[];
public ServerSocket server = null;
public Thread thread = null;
public int clientCount = 0, port = 9999;
public ServerFrame ui;
public Database db;

public SocketServer(ServerFrame frame) {
clients = new ServerThread[50];
ui = frame;
db = new Database(ui.filePath);
try {
Nhóm 2 – Mạng máy tính K56

×