Saturday, June 9, 2007

Chat Program - Học Java - Bài 6

Xem code của file: CreateNewChatClient.java
Đây có thể xem là lớp quan trọng nhất của phần Server.
Nhiệm vụ của lớp này là tạo mới một bộ lưu trữ cho Client kết nối đến, thực hiện các chức năng của phần Server, kết nối các Client với nhau và chạy song song với các Thread khác để đảm bảo không bị trễ khi các Client muốn làm việc với nhau.
7. implements Runnable : Dòng này nhằm thừa kế lại lớp Runnable của Java để có thể chạy song song lớp này.
8. private boolean finished = false; Đánh dấu xem lớp có cần dừng hay không, nếu dừng chương trình sẽ chấm dứt luôn Thread này.
9. private Socket client; Dùng để lưu một bản copy của Client kết nối đến
10. private String myNick; Tên của Client kết nối đến
11. private String myPass;
12. private boolean loginned=false; Đánh dấu xem đã login chưa, nếu đã login các chức năng tương ứng sẽ được kích hoạt

Để hiểu được hai biến này bạn phải biết chút ít về luồng nhập và xuất trong Java.
14. BufferedReader inStream; Luồng vào, nó chịu trách nhiệm kết nối đến luồng vào của lớp và đọc dữ liệu
16. BufferedWriter outStream; Luồng ra, nó sẽ xuất dữ liệu ra luồng này, để cho lớp khác đọc dữ liệu, hoặc chính nó.
Ví dụ: Chúng ta có 2 lớp: 1 Lớp A từ phía Client kết nối đến Server với giao thưc là TCP (không dùng UDP, nếu không sẽ mất kết nối), ở Server nó sẽ tạo ra 1 lớp tương ứng với lớp A của Client và copy toàn bộ thông tin của lớp A đó (hiển nhiên có thông tin luồng vào và ra). Khi lớp A gửi thông tin đến luồng ra của nó, thì phía Server nó sẽ nhận được thông tin ở phía luồng vào và ngược lại. Đọc tiếp phần dưới.
19. public CreateNewChatClient(Socket newClient) : newClient đây chính là lớp Socket của Client kết nối đến, nó sẽ được lớp chính ChatServer truyền vào để lấy dữ liệu.
20->24 : Copy và lấy luồng nhập/xuất
Tiếp theo, kéo xuống dòng 216, bạn sẽ thấy một hàm public void run() : Hàm này là của lớp Runnable, được cài đặt lại, hàm này có trách nhiệm làm cho lớp này chạy song song.
219. while (!finished) : Lặp hoài không dừng, nhằm mục đích lấy dữ liệu ở luồng vào của lớp, nó sẽ dừng khi phía Client tắt cái của sổ chat (:D).
Bây giờ có lẽ bạn sẽ hỏi một câu: Tại sao phải rườm ra như vậy, dùng thẳng lệnh lặp mãi mãi này được rồi, tạo Thread gì cho mệt, câu trả lời sẽ là: Nếu bạn chạy vĩnh viễn mà không dùng Thread thì chương trình sẽ treo ngay. Còn nếu bạn không chạy vĩnh viễn thì nếu được bạn chỉ lấy được dữ liệu một lần ở luồng vào mà thôi (sau khi lấy xong lớp sẽ kết thúc luôn). Tốt nhất bạn nên viết thử một đoạn code để test 2 trường hợp này để rõ hơn (chú ý khi lặp vĩnh viễn thì nhớ cài Thread nhé, không thì treo máy đó).
220. Dòng này để đọc dữ liệu ở dòng vào nếu không có nó sẽ trả về là null.
222. Dòng này là gửi dữ liệu đến hàm processMessage để xử lý (bạn cũng có thể xử lý ở ngay trong này nhưng sẽ rất lộn xộn).
141. private void processMessage(String str) : Hàm xử lý các thông điệp, biến str sẽ lưu thông điệp cân xử lý nó theo một cấu trúc nhất định.
Cấu trúc: Mã_Thông_Điệp,Nội_dung_1,Nội_dung_2 Bạn có thể thiêt kế đoạn này thành một lớp cho nó pro (:D).
Các thông điệp trong chương trình
1. Thông điệp tạo nick mới: 1, user, pass
2. Thông điepj login: 2, user, pass
3. Thông điệp yêu cầu kết nối đến Client khác: 3, tên client muốn kết nối
4. Thông điệp gửi message đến Client đang kết nối: 5, tên nick, thông điệp
5. Thông điệp yêu cầu lấy tên tất cả các nick có trên Server: 6
6. Thông điệp báo cho Server biết là Client đã thoát: 7
Xem đoạn code của hàm rồi đọc phần tiếp, hãy khoan rê chuột đến hàm tương ứng để xem
48. private void createNewNick(String newNick, String pass) : Hàm này hỗ trợ cho thông điệp 1, chẳng có gì khó nó đọc file Nick.txt xem đã có nick chưa, nếu chưa thì tạo mới, bạn có thể thay bằng CSDL cho pro, vì mục đich của mình là chương trình chat nên mình chỉ dùng text thôi.
87. private boolean login(String nick, String pass) : Hàm này hỗ trợ thông điệp 2, tương tự hàm createNewNick, Nếu thành công nó sẽ cập nhật 2 giá trị nick, pass và gửi trả lại thông điệp 21 cho Client, thông điệp này báo rằng đã login thành công ngược lại là thông điệp 20.
123. private void connectOtherClient(String nickB)
: Hàm này hỗ trợ thông điệp 3, có một xí phức tạp
124. sendMessage(nickB, "3"+myNick)
; nickB là nick của Client khác mà Client này muốn kết nối, cấu trúc yêu cầu là "3"+myNick.
134. sendMessage : 135. Kiểm tra xem Client này đã login chưa, nếu chưa thì không cho phép, 136. Tìm nickB trong bộ lưu trữ của Server xem có không, 137. Nếu tồn tại nickB thì gửi thông điệp yêu cầu chat đến nó nó dùng hàm này để gửi(tự gửi tới nó) sendMessageToMe, message có cấu trúc là 3nickA, chú ý điểm này nhé lệnh của nó là nC.sendMessageToMe(message); chứ không phải nó gọi hàm sendMessageToMe ở dòng 28 đâu đấy.
28. public void sendMessageToMe(String message) : Hàm này chỉ có nhiệm vụ là ghi chuỗi message vào luồng ra để cho dòng 220 trong hàm run đọc.
129. private void chatMessage(String nickB, String message) : Tương tự hàm sendMessage nhưng thông điệp của nó là 5, dùng để gửi câu chat.
181 và 203 chắc không cần giải thích thêm.

Chat Program - Học Java - Bài 5

Xem code của file: AllClientData.java
- Class này nhằm lưu trữ thông tin của mọi Client kết nối đến Server.
- Class này sử dụng lớp Vector chuẫn để tạo ra một mảng lưu trữ cho Server, mục đích việc sử dụng lớp Vector là vì lớp này khá linh hoạt và nó không phân biệt kiểu đối tượng được lưu trong lớp đó.
- Các phương thức trong lớp này đều là static, bởi vì lớp này khá nhỏ không sợ tốn bộ nhớ nhiều khi tạo nó theo kiểu static và hơn nửa nó sẽ thuận tiện hơn trong việc truy cập từ lớp khác(không cần tạo mới nhiều lần).
- Các phương thức trong lớp khá rõ ràng, chỉ cần bạn đã học Java là có thể hiểu ngay

Friday, June 8, 2007

Chat Program - Học Java - Bài 4

Xem code của file này: ChatServer.java
15. ServerSocket server = new ServerSocket(2222); dòng này có nghĩa là tạo một socket mới với IP là địa chỉ máy bạn chạy server và ở cổng 2222, cổng này có thể đổi tùy ý, tuy nhiên tránh mấy cổng mặc định ra: Http(80), FTP(21), ...
19. AllClientData ar=new AllClientData(); Khởi tạo một danh sách các bộ lưu trữ các client trên server, nó sẽ lưu thông tin của tất cả các client kết nối đến.
20. while (true) nó có nghĩa là chạy hoài không dừng, nhằm mục đích là chờ kết nối của 1 client mới
22. Socket client = server.accept(); đây là một lệnh chờ kết nối, khi gặp lệnh này chương trình sẽ dừng lại và chờ đợi kết nối mới, khi có kết nối mới nó sẽ tiếp tục thực hiện nhưng lệnh kế tiếp
29. CreateNewChatClient x=new CreateNewChatClient(client); tạo bộ lưu trữ client mới
30. ar.add(x); đưa vào danh sách lưu trữ
31. new Thread(x).start(); thực thi các chức năng của bộ lưu trữ này
Tập 3 lệnh này nhằm lưu trữ thông tin client mới kết nối đến vào bộ nhớ, và thực thi các chức năng của bộ lưu trữ này, bộ này sẽ chạy song song <=> 1 thread của window.
Khi 2 client tương tác với nhau, server sẽ tạo một kết nối giữa 2 bộ lưu trữ của 2 client đó để cho nó có thể tự động tương tác với nhau sẽ nói rõ hơn trong phần CreateNewChatClient.

Chat Program - Học Java - Bài 3

Thiết kế Client, nó không phức tạp giống server, nó thiên về giao diện sử dụng hơn.
Nhiệm vụ chính của client là:
- Kết nối server
- Login vào để dùng
- Khi người khác chat với mình thì hiển thị cửa sổ chat
- Phân tích được các thông điệp mà server gửi về
- ...
Phần này gồm có 7 file: Xem ở đây.

Thursday, June 7, 2007

Chat Program - Học Java - Bài 2

Để hoàn thiện một chương trình Chat thì bạn cần có đến hai phần: Server và Client

Phần này sẽ nói đến Server, để trở thành một Server thì nó cần:
- Chạy ở 1 IP cụ thể và ở một cổng xác định (bởi vì các client cần biết server đang chạy ở đâu và cổng nào để kết nối đến)
- Phải biết được ai vừa kết nối đến server và trả lời khi kết nối thành công
- Duy trì được các kết nối từ các client khác nhau (để lần sau có thể gửi hay nhận thông tin)
- Định nghĩa "một tập lệnh/API" cho client sử dụng: có nghĩa là server chịu trách nhiệm đưa ra cấu trúc của thông điệp được truyền đi giữa client-server, mỗi thông điệp sẽ ứng với một chức năng và thông tin cụ thể, server phải phân tích được thông điệp để thực hiện chức năng tương ứng. ví dụ: thông điệp truyền đi "1:login,pass" có nghĩa là yêu cầu server cho phép login với user: login và password: pass ...

Phần này gồm có 3 file: Xem ở đây

Wednesday, June 6, 2007

Chat Program - Học Java - Bài 1

Giới thiệu:
Có lẽ bạn cũng như tôi, khi bắt đầu học Java, tài liệu Java thì rất nhiều nhưng rất ít tài liệu bày cách viết một ứng dụng hoàn chỉnh với Java, cách kết nối các hàm Java với nhau để nó hoạt động, ...
Và do đó trong những bài này mục đích của mình không phải là bày cho các bạn về Java (có rất nhiều sách đã làm việc này) mà bày cách làm một ứng dụng nhỏ, hoàn chỉnh và thực tế có thể dùng được dựa trên ngôn ngữ lập trình Java.

Trong tất cả các bài học mình sẽ giải thích nhưng đoạn code mà mình cho là khó hiểu, những đoạn code và thuật toán trong các bài có thể chưa được hay, mình sẵn sàng đón nhận những góp ý đàng hoàng mong bạn đừng comment những lời không tốt, không tế nhị.

Mục đích của chương trình này là viết một phần mềm hỗ trợ việc chat nội bộ giữa 2 hay nhiều máy tính với nhau, đơn giãn thôi không phức tạp giống như Jh chat đâu :) .
Chương trình này mình chưa test trên mạng Internet, nhưng theo lý thuyết thì nó có thể chạy trên Internet.

Những thứ cần chuẩn bị:
- Một ít hiểu biết về mạng như IP, TCP, UDP, ...
- Đã biết một ít về java.
- Một số chương trình soạn thảo Java như: UltraEdit, EditPlus, Eclipse, ...
Rồi có thế thôi, bắt đầu nhé.

Download toàn bộ source code và class, jar file.