- Kiểm tra sự kết nối giữa Client và Server.
Mô tả trường hợp: Client và Server đã được kết nối. Nhưng Server bị Shutdown.
Khó khăn cần giải quyết là làm sao thông báo cho Client biết là Server đã Shutdown.
Chương trình của bọn em còn thụ động, chỉ khi nào Client gởi thông điệp không thành công thì nó mới biết Server đã Shutdown.
Bọn em đã thử dùng 1 thread sử dụng phương thức getKeepAlive của lớp Socket đảm nhiệm nhiệm vụ kiểm tra. Nhưng không thành công.
- Chức năng resume là 1 chức năng rất quan trọng của bất cứ 1 chương trình FTP nào. Đây thực sự là 1 vấn đề cần sự đầu tư nghiêm túc.
8 trang |
Chia sẻ: netpro | Lượt xem: 3898 | Lượt tải: 2
Bạn đang xem nội dung tài liệu Đề tài Viết một chương trình FTP đơn giản bằng ngôn ngữ Java, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Báo cáo về bài tập thực hành nâng cao.
Đề bài: Viết một chương trình FTP đơn giản bằng ngôn ngữ Java.
========
Tổ 7:
Thành viên:
+ Nguyễn Đức Khanh.
+ Nguyễn Thị Phú.
+ Phan Xuân Phước.
+ Nguyễn Thị Tuyết Trinh.
+ Bùi Thị Ngọc Hiền
FTP viết theo theo mô hình Client & Server.
Server có thể phục vụ đồng thời nhiều Client.
Điều này nhờ sự hỗ trợ đa luồng của Java, chương trình Server của nhóm em kế thừa lớp Thread để làm được điều này.
Chương trình thực hiện 2 chức năng chính của 1 chương trình FTP là: upload và download.
Để kết nối Client và Server, ta dùng Socket và ServerSocket.
+ phương thức upload được mô tả như sau:
+ Client gởi file lên Server:
Đặt file cần upload vào 1 luồng nhập xuất:
DataInputStream dataIn = new DataInputStream ( new BufferedInputStream( new FileInputStream ( tmpFile ) ) );
Đọc 1 số n byte từ file, cho vào 1 mảng. Sau đó gởi lên Server mảng dữ liệu đó.
Để gởi được 1 đối tượng, ta dùng luồng nhập xuất
ObjectInputStream, ObjectOutputStream. Với 2 phương thức chính là:
Object readObject( ) : đọc 1 đối tượng có kiểu Oject trong luồng nhập
Object writeObject( ) : xuất 1 đối tượng có kiểu Oject ra luồng xuất.
Quá trình đọc file sẽ dừng khi ta đọc được byte có giá trị - 1;
+ Server nhận file được gởi lên từ Client.
Đọc đối tượng (là mảng chứa dữ liệu file cần upload)
Lần lượt ghi dữ liệu trong mảng vào file cho đến khi đọc hết mảng.
Quá trình sẽ dừng khi Server đọc được 1 byte có giá trị là -1;
+ phương thức download thực hiện tương tự.
====
Đó là dạng mô tả thô cho quá trình cần làm. Trong thực tế ta cần phải kiểm tra sự tồn tại của file, thư mục…..
Sau đây là trình bày chi tiết về các lớp, các phương thức được sử dụng trong chương trình.
I. Client :
Client có giao diện đồ họa Swing của Java. Gồm 3 lớp:
+ G7FTP.class: lớp chính hiển thị đồ họa và thực hiện upload, download file.
+ FileModel.class và FileRenderer.class: thể hiện tên, size, icon file và thư mục của Client và Server lên JTable được thiết kế trong chương trình.
1. Lớp G7FTP:
- Lớp G7FTP cài đặt các giao diện: ActionListener, ListSelectionListener, MouseListener.
- Các phương thức được cài đặt trong lớp G7FTP:
a. Nhóm các phương thức thể hiện giao diện:
- public G7FTP(): phương thức khởi tạo. Khởi tạo frame chính của chương trình client fmainClient, gắn các Listener lên fmainClient, các button, bảng, các menuItem.
- public void createComponentGUI(): trình bày các thành phần đồ họa trên chương trình Client
- public void createTableViewFile(): thể hiện danh sách file và thư mục của máy client trên một JTable.
- public void createTableViewFileServer(): khởi tạo 1 JTable thể hiện danh sách file và thư mục của Server, ban đầu là 1 bảng rỗng.
Các lớp này được gọi bởi phương thức khởi tạo.
b. Nhóm các phương thức trình bày sự thay đổi folder trên máy client lên chương trình:
- public String getParentPath(String currentPath)
- public String getParentPath(File currentFileDir)
+ Mục đích: trả lại tên thư mục cha của thư mục hiện hành.
+ Phương thức được gọi mỗi khi người dùng thay đổi thư mục của phần hiển thị file và folder trên máy client, và được gọi bởi phương thức: changeFileView(String path)
- public void setTextLocationClient(String title)
+ Mục đích: đặt lại tên thư mục hiện hành trên button btLocationPathClient thể hiện tên thư mục hiện hành.
+ Phương thức được gọi bởi phương thức: changeFileView(String path)
- public void changeFileView(String path)
+ Mục đích: thể hiện lại danh sách folder và file trong bảng tableFileListClient trên máy client khi người dùng thay đổi thư mục.
+ Phương thức được gọi mỗi khi người dùng nhấp vào 2 button btLocationPathClient, btGotoParentPathClient và folder trên bảng tableFileListClient , và được gọi bởi phương thức:
public void actionPerformed(ActionEvent actEvent)
public void mouseClicked(MouseEvent mouseEvent)
c. Nhóm các phương thức trình bày sự thay đổi folder trên Server:
- public void setTextLocationServer(String title)
+ Mục đích: đặt lại tên thư mục hiện hành của Server trên button btLocationPathServer
+ Được gọi bởi phương thức: changeFileViewServer(Object[][] data)
- public void changeFileViewServer(Object[][] data)
+ Mục đích: thể hiện lại danh sách file và folder của Server lên bảng tableFileListServer, danh sách file và folder trên thư mục hiện hành của Server được lưu giữ bởi mảng Object[][] data.
+ Được gọi bởi phương thức: refreshFileViewServer()
- public void refreshFileViewServer()
+ Mục đích: nhận tên thư mục hiện hành, tên thư mục cha của thư mục hiện hành và danh sách file, folder của thư mục hiện hành trên Server
+ Được gọi bởi phương thức: changeFolderServer(String folderName)
- public void changeFolderServer(String folderName)
+ Mục đích: gởi thông điệp CHANGE_FOLDER tới Server và sau đó gởi tên thư mục mà người dùng muốn chuyển đến trên Server.
+ Phương thức được gọi mỗi khi người dùng nhấp vào button btGotoParentPathServer và folder trên bảng tableFileListServer, và được gọi bởi phương thức:
public void actionPerformed(ActionEvent actEvent)
public void mouseClicked(MouseEvent mouseEvent)
d. Cài đặt các phương thức của các giao diện:
- public void actionPerformed(ActionEvent actEvent)
+ Thực hiện các hành động: kết nối, ngắt kết nối, upload, download, thay đổi thư mục, refresh.
- public void mouseClicked(MouseEvent mouseEvent)
+ Bắt sự kiện bấm chuột của người dùng trên 2 bảng tableFileListClient, tableFileListServer. Thực hiện việc thay đổi thư mục.
- public void valueChanged(ListSelectionEvent lsEvent)
+ Là phương thức của giao diện: ListSelectionListener
+ Bắt sự kiện người dùng dùng chuột chọn các file và folder trên 2 bảng tableFileListClient, tableFileListServer. Cho biết danh sách các dòng được chọn trên 2 bảng tableFileListClient, tableFileListServer.
e. Nhóm các phương thức kết nối và ngắt kết nối với Server:
- public boolean connect()
+ Mục đích: tạo kết nối với Server và trả lại kết quả kết nối.
+ Được gọi khi người dùng nhấp vào button btConnect, và đựoc gọi bởi phương thức: public void actionPerformed(ActionEvent actEvent).
- public void disConnect()
+ Mục đích: ngắt kết nối với Server.
+ Được gọi bởi phương thức: public void actionPerformed(ActionEvent actEvent).
g. Nhóm các phương thức truyền tải file:
- public void upLoad(String[] filesUpLoaded)
+ Mục đích: upload danh sách các file lên Server.
+ Được gọi bởi phương thức: actionPerformed(ActionEvent actEvent).
+ Code:
File tmpFile = new File("fileUpload");
DataInputStream dataIn = new DataInputStream( new BufferedInputStream (new FileInputStream (tmpFile) ) );
int ch = 0;
int count = 0;
Integer[] myBit = new Integer[LENGTH_MY_BLOCK_FILE];
int sttKhoi = 1;
do
{
ch = dataIn.read(); // đọc 1 byte trong luồng nhập file
myBit[count] = new Integer(ch); // ghi byte vua doc vao mang
count++;
if ((count = = LENGTH_MY_BLOCK_FILE) || (ch = = -1))
{
// goi mang du lieu len Server
//System.out.println("Dang goi khoi thu " + sttKhoi);
//1. goi so luong phan tu cua mot khoi
objOut.writeInt(count);
//2. goi 1 khoi cua file len Server.
objOut.writeObject(myBit);
objOut.flush();
//3. reset count and myBit[]
count = 0;
myBit = new Integer[LENGTH_MY_BLOCK_FILE];
/*
if (ch = = -1)
System.out.println("Da goi xong khoi "+sttKhoi+"; Khoi cuoi cung. Dang doi Server tra loi" );
else
System.out.println("Da goi xong khoi "+sttKhoi+"; .Dang doi Server tra loi" );
String ss2 = objIn.readUTF();
System.out.println("Server tra loi: " + ss2);
sttKhoi++;
*/
}
}
while (ch != -1);
dataIn.close();
- public void downLoad(String[] filesDownLoaded)
+ Mục đích: download các file từ Server xuống máy client.
+ Được gọi bởi phương thức: actionPerformed(ActionEvent actEvent).
2. Lớp FileModel
- Lớp FileModel kế thừa lớp trừu tượng AbstractTableModel.
- Trình bày tên file, folder và kích thước file lên JTable.
- Các phương thức được cài đặt trong lớp FileModel:
a. Nhóm các phương thức khởi tạo:
- public FileModel()
- public FileModel(Object[][] arrayFileServer)
- public FileModel(String dir)
ghi dữ liệu: tên file, tên folder, kích thước file vào mảng Object data[][]
b. public void setFileStats(File dir, String dirpath)
+ Mục đích: Cài đặt danh sách file, folder, file size lên mảng Object data[][]
+ Được gọi bởi phương thức khởi tạo.
c. Tường minh các phương thức của lớp trừu tượng AbstractTableModel
- c1. public int getRowCount() { return data.length; }
- c2. public int getColumnCount() { return titles.length; }
- c3. public String getColumnName(int c) { return titles[column]; }
- c4. public Class getColumnClass(int column) { return types[column]; }
- c5. public Object getValueAt(int row, int column) { return data[row][column]; }
+ c1, c2: Trả lại số dòng, số cột trong 1 JTable sử dụng FileModel.
+ c3, c4: Trả lại tên cột, lớp dữ liệu của 1 cột được lưu trong bảng JTable.
+ c5: Trả lại giá trị dữ liệu tại 1 cell xác định.
3. Lớp FileRenderer:
- Lớp FileRenderer kế thừa lớp DefaultTableCellRenderer
- Thể hiện Icon lên cell của JTable.
- Các phương thức được cài đặt:
a. Phương thức khởi tạo: public FileRenderer()
+ Định dạng sự canh lề của các cột trong JTable.
b. Phương thức thể hiện Icon lên cell:
- public Component getTableCellRendererComponent (JTable table,
Object value, boolean isSelected, boolean hasFocus, int row, int col)
+ Là phương thức nạp chồng của lớp DefaultTableCellRenderer. thể hiện icon file, folder lên cell.
II. Server:
Server gồm 2 lớp:
+ G7FTPServer.class: gồm 1 phương thức main, khởi tạo ServerSocket, sau đó gọi phương thức khởi tạo của lớp G7TransferFile
+ G7TransferFile.class: đóng vai trò chủ đạo, thực hiện việc truyền tải file.
1. Lớp G7TransferFile:
- Lớp G7TransferFile kế thừa lớp Thread, thể hiện khả năng đa luồng của Server.
- Các phương thức được cài đặt:
a. Phương thức khởi tạo:
- public G7TransferFile(Socket soc)
+ Thực hiện việc kết nối với Client và gọi phương thức start() của Thread để chạy phương thức run()
b. Phương thức run()
- Được cài đặt với 1 vòng lặp không dừng, chờ đón nhập các yêu cầu của Client, và ứng với mỗi yêu cầu sẽ gọi các phương thức tương ứng để đáp lại các yêu cầu đó.
c. Các phương thức:
- public String getCurrentDirPath()
- public String getParentDirPath(String fileName)
- public String getParentDirPath(File file)
+ Trả lại tên thư mục hiện hành và tên thư mục cha của thư mục hiện hành trên Server.
+ Được gọi bởi nhóm các phương thức hành động.
c. Nhóm các phương thức hành động:
- public void sendServerFileSystem()
+ Gởi tên thư mục cha của thư mục hiện hành, tên thư mục hiện hành và danh sách các file, folder của thư mục hiện hành trên Server cho client.
+ Phương thức được gọi mỗi khi Client kết nối với Server hay các tình huống client cần refresh lại bảng thể hiện file, folder của Server trên chương trình Client.
- public void receiveFileFromClient()
+ Đáp ứng lại thông điệp upload của client. Nhận file do người dùng upload lên Server.
+ Code:
File tmFile = new File("file duoc upload");
DataOutputStream dataOut = new DataOutputStream (new BufferedOutputStream (new FileOutputStream (tmpFile) ) ); int ch = 0;
int kt = 0; // luu kich thuoc 1 khoi file duoc goi len tu client
Integer bitFile = new Integer(0); Integer[] myBit = new Integer[LENGTH_MY_BLOCK_FILE];
int sttKhoi = 1;
do
{
//System.out.println("Dang nhan khoi thu " + sttKhoi);
// 1. nhan so byte trong 1 khoi
kt = objIn.readInt();
// 2. nhan khoi du lieu cua file
myBit = (Integer[])objIn.readObject();
// 3. ghi thong tin len file
for ( int i = 0; i < kt; i++)
{
ch = myBit[i].intValue();
//System.out.print(ch+ "; ");
if (ch != -1)
{
dataOut.write(ch);
dataOut.flush();
}
}
/*
System.out.println("\t da nhan va ghi xong khoi "+sttKhoi+ " vao file");
objOut.writeUTF("da nhan ghi xong khoi "+sttKhoi);
objOut.flush();
sttKhoi++;
*/
}
while (ch != - 1);
dataOut.close();
//= = = = = = = = = =
- public void sendFileToClient()
+ Đáp ứng lại thông điệp download của client. Gởi file (nếu tồn tại) mà client yêu cầu download xuống máy client.
=====================================
Sau đây là những nhận xét của chúng em về bài tập nhóm:
+ Những khó khăn chính bọn em hiện chưa nghĩ ra phương án giải quyết:
- Kiểm tra sự kết nối giữa Client và Server.
Mô tả trường hợp: Client và Server đã được kết nối. Nhưng Server bị Shutdown.
Khó khăn cần giải quyết là làm sao thông báo cho Client biết là Server đã Shutdown.
Chương trình của bọn em còn thụ động, chỉ khi nào Client gởi thông điệp không thành công thì nó mới biết Server đã Shutdown.
Bọn em đã thử dùng 1 thread sử dụng phương thức getKeepAlive của lớp Socket đảm nhiệm nhiệm vụ kiểm tra. Nhưng không thành công.
- Chức năng resume là 1 chức năng rất quan trọng của bất cứ 1 chương trình FTP nào. Đây thực sự là 1 vấn đề cần sự đầu tư nghiêm túc.
+ Những hạn chế của chương trình:
- Khả năng upload, download thực sự là chưa đáp ứng được yêu cầu. Có lẽ nhóm bọn em cần thêm 1 khoảng thời gian để hoàn thiện chức năng này.
- Chương trình của bọn em còn đơn giản, chưa upload, download được thư mục, chưa có các chức năng delete, new folder, rename… nếu có thời gian nhóm em có thể sẽ hoàn thiện được các chức năng này.
- Khả năng di chuyển, thay đổi thư mục trên Server còn bó hẹp. Dự định bọn em sẽ dùng 1 JTree để thể hiện cây thư mục trên Server. Khi người dùng nhấp vào button chuyển thư mục, JTree sẽ hiển thị và người dùng có thể chọn thư mục trên server để chuyển đến.
+ Những khó khăn đã giải quyết được:
- Hiển thị danh sách file, folder trên Client và Server. Điều này đã được bọn em thực hiện khá triệt để nhờ sử dụng JTable. Khó khăn lớn nhất khi sử dụng JTable là hiển thị Icon lên các cell của nó. Điều này bọn em đã giải quyết được.
+ Những điều thu nhận được sau khi làm bài thực hành:
- Bổ sung kiến thức. Thực sự bọn em đã đọc tài liệu rất nhiều, và hầu hết là tài liệu tiếng Anh. Biết thêm được nhiều cái hay của Java, đó là khả năng lập trình mạng và MultiThread.
- Tuy nhiên vì thời gian làm bài, khả năng còn hạn chế, khả năng phối hợp giữa các thành viên chưa tốt nên chương trình của bọn em vẫn chưa hoàn thiện. Bài tập nhóm lần này là 1 đợt kiểm tra bổ ích cho bọn em về khả năng, kỹ năng làm việc.
Bọn em sẽ cố gắng hoàn thiện chương trình vào thời gian sau này, hi vọng thầy sẽ thích thú hơn với phiên bản sau của chương trình.
Và cuối cùng, em thay mặt cả nhóm xin cảm ơn thầy đã dạy cho chúng em những kiến thức quý báu để bọn em hoàn thành được chương trình này.
Quy Nhơn, 29/6/2005, Người viết báo cáo:
Nguyễn Đức Khanh
Tin K25 – Khoa Tin – Đại học Quy Nhơn.
Các file đính kèm theo tài liệu này:
- Viết một chương trình FTP đơn giản bằng ngôn ngữ Java.doc