Đồ án Dịch vụ thư tín điện tử và cài đặt một chương trình mang tính thử nghiệm do dịch vụ thư tín điện tử

Cần chú ý rằng việc attach một tập tin vào mail cần phải được thực hiện đồng bộ giữa người gửi , người nhận và đường truyền thư.Nếu không có sự đồng bộ, nội dung của tập tin được attach có người nhận không đọc được. Lý do của việc này là do nội dung của tập tin được attach sẽ được mã hoá theo UUENCODE hay theo MIME (Multipurpose Internet Mail Extensions).

pdf151 trang | Chia sẻ: lylyngoc | Lượt xem: 2420 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Đồ án Dịch vụ thư tín điện tử và cài đặt một chương trình mang tính thử nghiệm do dịch vụ thư tín điện tử, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ác thuộc tính khác khi giá trị của thuộc tính này phụ thuộc vào giá trị của thuộc tính kia. Sự phụ thuộc có thể là trực tiếp hay gián tiếp.  Một quan hệ bao giờ cũng có một nhóm thuộc tính mà giá trị của chúng qui định giá trị của các thuộc tính khác, nhóm thuộc tính đó gọi là khóa.  Với một quan hệ tùy vào các phụ thuộc của các thuộc tính vào khóa trong đó mà ta phân chia các quan hệ đó thành các dạng chuẩn khác nhau. Các dạng chuẩn cơ bản: Dạng chuẩn 1 Dạng chuẩn 2 Dạng chuẩn 3 Các dữ liệu lưu giữ dưới dạng chuẩn 3 tránh được hiện tượng dư thừa dữ liệu, tạo cho dữ liệu có tính độc lập cao. Các quan hệ nếu chưa ở dạng chuẩn 3 sẽ được phân rã thành các quan hệ nhỏ hơn ở dạng chuẩn 3. 2.3.3 Khái niệm chỉ dẫn và khóa chỉ dẫn Để có thể tìm kiếm thông tin nhanh theo một tiêu chuẩn nào đó chúng ta tạo ra các thông tin chỉ dẫn theo tiêu chuẩn đó. Các thông tin chỉ dẫn là các thông tin giúp ta tìm kiếm dữ liệu nhanh. Các thông tin này gọi là khóa chỉ dẫn . Khóa chỉ dẫn có thể là một trường, hoặc nhiều trường . Với cách tạo ra khóa chỉ dẫn theo tiêu chuẩn nào đó ta có thể tìm kiếm nhanh dữ liệu theo tiêu chuấn đó. 2.4.GIỚI THIỆU VỀ JAVA SERVLET 2.4.1.Khái niệm về JAVA SERVLET Mã nguồn của Servlet dược biên dịch ra mã byte – code của Java. Servlet dễ sử dụng và phát triển những ứng dụng Web nhanh hơn CGI. Servlet chạy tự động khi chúng được gọi từ trình chủ (Web server) . Servlet chạy toàn bộ trên máy ảo Java, xử lý và sinh mã HTML trả về trình khách. Bằng cách này Servlet có thể chạy trên rất nhiều trình chủ hiểu Java và chúng không phụ thuộc và trình duyệt (browser). 2.4.2.Những ứng dụng thực tế của JAVA SERVLET và kiến trúc của JAVA SERVLET Servlet có thể được sử dụng trong bất kỳ một ứng dụng nào liên quan đến Web. Hai gói tạo nên kiến trúc của Java Servlet là : javax.servlet và javax.servlet.http. Gói javax.servlet chứa đựng phần giao diện tổng quát phục vụ cho Servlet. javax.servlet.http chứa đựng các lớp phục vụ cho giao thức triệu gọi HTTP. Bộ khung hình thành nên Servlet bao gồm các phương thức sau: init() Phương thức khởi tạo servlet. service() Phương thức nhận và trả lời từ phía người sử dụng. destroy() Phương thức thực hiện việc huỷ servlet. Các tập tin Servlet đều được đặt trong giao diện bao gồm các phương thức trên. Chúng rất rõ ràng trong giải pháp lập trình đối tượng và dễ dàng mở rộng. 2.5.GIỚI THIỆU VỀ JAVA SERVER PAGES(JSP) 2.5.1.Khái niệm về JSP JSP là công nghệ rất mạnh để tạo trang HTML động về phía trình chủ. JSP là phần mở rộng trực tiếp của Java Servlet, bộ diễn dịch JSP sẽ ánh xạ trực tiếp mã JSP thành Servlet. Viết trang JSP ta không cần phải thông qua quá trình biên dịch tập tin thực thi .class như trong Servlet. JSP cung cấp mô hình lập trình Web dễ dàng và tiện dụng hơn Servlet. Công việc biên dịch trang JSP được thực hiện tự động bởi trình chủ. 2.5.2.Quan hệ giữa Servlet và JSP 2.5.2.1.Cách trình chủ biên dịch trang JSP thành servlet Thật sự các trang JSP được trình chủ dịch ra thành servlet trước khi cho thực thi. Khi trình khách triệu gọi trình chủ Web server sẽ thực hiện các bước sau: Bước 1: Kiểm tra trang JSP đã được dịch ra thàn mã nguồn tương đương của servlet chưa. Bước 2 : Nếu chưa biên dịch trang JSP thành file nguồn thành file nguồn .java theo cấu trúc của servlet. Gọi trình biên dịch javac biên dịch file nguồn .java thành file thực thi của servlet .class. Bước 3 : Nạp servlet đã biên dịch ở bước 2, thực thi kết quả trả về cho trình khách. Bước 4 :Nếu file JSP đã được biên dịch trước đó : thực hiện việc kiểm tra xem nội dung file JSP có thay đổi hay không. Nếu có, quay lại bước 2 biên dịch lại trang. Nếu không thực hiện lại bước 3. 2.5.2.2. So sánh giữa Servlet và JSP Do mã trang JSP thi thực thi đều được biên dịch ra servlet cho nên tất cả những gì servlet làm được cũng đồng nghĩa với trang JSP làm được. Viết trang JSP đôi khi đơn giản hơn trang servlet vì không cần phải qua bước đăng ký và biên dịch thủ công. JSP có thể trộn lẫn mã java với các thẻ HTML nên việc thiết kế trang JSP thường đơn giản và dễ bổ sung hơn so với servlet. Tuy nhiên đây cũng là yếu tố không nên lạm dụng đối với JSP. Nếu tập trung tất cả mã Java vào cùng với mã HTML thì một khi dự án mở rộng và trở nên phức tạp tất nhiên việc bảo trì và nâng cấp ứng dụng Web với hàng trăm trang JSP sẽ rất khó khăn. Trong quá trình phát triển ứng dụng Web theo nhóm, việc trộn lẫn mã Java và HTML trong trang JSP cho thấy không hiệu quả. Khó có thể tách rời giữa công việc viết mã cho ứng dụng (thường là vai trò của lập trình viên – programmer) và nhóm xây dựng giao diện (nhóm thiết kế Web – Web designer). Mã trang JSP ở dạng thuần văn bản nên thường không che được mã nguồn của logic chương trình. Với servlet tuy phải biên dịch và đăng ký thủ công với trình chủ nhưng bù lại tính bảo mật cao hơn. Ta chỉ cần cung cấp cho trình chủ Web Server bản servlet nhị phân ( file .class ) đã qua bước biên dịch mà không cần đến mã nguồn của servlet ban đầu. Mặt khác, các servlet có thể tương tác liên hoàn với nhau để tạo nên những kết xuất tuỳ biến và đa dạng trước khi trả kết quả về cho trình khách. Servlet có thể phân rã các đơn thể của dự án và phát triển độc lập nhau như các thành phần riêng biệt để ráp lại trong một tổng thể chung. Mặc dù vậy, việc kết xuất trong servlet thường dựa vào phương thức print() hoặc println() nên việc kết xuất phụ thuộc vào lập trình viên với hàng loạt các lệnh print() và println() rất khó quản lý. Việc quyết định sử dụng trang JSP, Servlet hay kết hợp cả hai là tùy vào từng dự án và mục đích của chương trình cần phát triển. Thông thường đối với những dự án nhỏ, yêu cầu thời gian nhanh, JSP là lựa chọn thích hợp nhất. Đối với những dự án cần sự độc lập và chỉ thiên về xử lý ta nên sử dụng servlet. Trường hợp dự án lớn ta nên kết hợp cả servlet và JSP. Mô hình kết hợp tốt nhất giữa servlet và JSP thường được gọi là MCV (Model – View – Controler) trong đó servlet đóng vai trò trung tâm điều khiển (controler) đưa ra quyết định xử lý, JSP đóng vai trò thể hiện giao diện hay hiển thị dữ liệu đã xử lý (View). Quy trình tính toán logic của ứng dụng được giao lại cho các thành phần JavaBean hay EJB. 2.6. GIỚI THIỆU VỀ JAVABEANS 2.6.1.Khái niệm về JAVABEANS JavaBeans là một thành phần đối tượng được xây dựng từ ngôn ngữ Java. JavaBeans có thể là việc và chạy trên mọi máy ảo Java. Yêu cầu tối thiểu nhất để tạo nên thành phần JavaBeans là : công cụ và trình biên dịch JDK 1.1 trở lên. JavaBeans có thể sử dụng các phương thức get/set để láy về và đặt thuộc tính cho đối tượng Bean mà nó thể hiện. 2.6.2.Các thẻ chuẩn của JAVABEANS trong trang JSP 2.6.2.1. Thẻ dùng để khai báo phạm vi và định danh id(identify) nhận dạng Bean. Nó tương tự như khai báo biến đối tượng trong mã java. Thẻ có cú pháp như sau: <jsp:useBean id=”name” scope=”page | request | session | application” class=”packagename.classname”> Thuộc tính Diễn giải Id Thuộc tính này là định danh nhận dạng của đối tượng Bean trong một phạm vi cho trước. “name” là tên của Bean có phân biệt chữ hoa, thường. Scope Thuộc tính phạm vi cho biết môi trường sống của đối tượng. Phạm vi của khai báo mà thành phần Bean có hiệu lực bao gồm page (Bean chỉ có hiệu lực và phạm vi truy xuất trong khai báo nó). Request (Bean có hiệu lực trong một lần yêu cầu từ máy khách). Session (hiệu lực của bean tương tự hiệu lực của các biến session). Application (hiệu lực của bean tương tự hiệu lực của các biến application) Class Tên đầy đủ của lớp Bean. Đây là tên tập tin .class sua khi đã biên dịch từ mã nguồn .java. tên này cũng phân biệt chữ hoa và chữ thường BeanName Này để tham chiếu đến tên của Bean Type Thuộc tính chỉ ra loại biến kịch bản. Nếu biến này không chỉ rõ giá trị của nó sẽ là giá trị của thuộc tính lớp 2.6.2.2. Thẻ dùng để gán giá trị vào thuộc tính Bean. Thuộc tính tên của Bean chỉ định cho đối tượng phải được định nghĩa và nằm trong phạm vi cho phép. Cú pháp của Trong cú pháp trên, name cho biết tên Bean mà thuộc tính của nó đã được cài đặt. prop_expr có thể có các khai báo sau: property =”*” | property = “propertyName” | property = “propertyName” param=”parameterName”| property = “propertyName” value=” propertyValue” Thuộc tính Diễn giải Name Thuộc tính trình bày tên của Bean, tên này đã được định nghĩa bởi thẻ Property Thuộc tính của Bean cần lấy giá trị Param Tham số cần dùng cho thuộc tính của Bean Value Giá trị được gán vào cho thuộc tính của Bean 2.6.2.3. Thẻ dùng để lấy giá trị thuộc tính Bean và chuyển giá trị thành kiểu chuỗi. Cú pháp cho thẻ như sau: Thuộc tính Diễn giải Name Thuộc tính trình bày tên của Bean, tên này đã được khai báo và định nghĩa bởi thẻ Property Thuộc tính của Bean cần lấy giá trị 2.6.3.Thêm JAVABEANS vào JSP Để sử dụng JavaBeans trong trang JSP, bạn cần khai báo Bean với thẻ: PHẦN 2 : XÂY DỰNG ỨNG DỤNG CHƯƠNG 1 PHÂN TÍCH BÀI TOÁN 1.1.TÊN ĐỀ TÀI Tìm hiểu xây dựng ứng dụng thư điện tử 1.2.DỀ CƯƠNG CHI TIẾT 1.2.1.Khảo sát Trong thời gian thực tập tốt nghiệp tôi đã khảo sát, tìm hiểu hệ thống thư tín điện tử. Quá trình xây dựng một ứng dụng thư điện tử (Email) rất đa dạng nhưng chủ yếu tập trung vào hai phần: ­ Xây dựng mail server : là chương trình hoạt động phía máy chủ nhận, lưu trữ mail, phân phối, gởi mail đến các trình chủ khác. Các chương trình như Mail Deamon, SendMail, Mail Exchange… là những mail server. ­ Xây dựng mail client : là chương trình hoạt động phía máy khách thực hiện chức năng cho phép người dùng nhập vào nội dung mail, gởi mail đến máy chủ mail server xác định. Nhận mail từ máy chủ về và hiển thị cho người dùng xem nội dung mail. Ví dụ như Outlook Express của Windows hay Web mail trên Internet là những trình đóng vai trò mail client. 1.2.2.Yêu cầu của bài toán Yêu cầu chính của bài toán ­ Phần mail client: thực hiện được cơ bản nhất những chức năng của một mail client như việc gởi, nhận, hiển thị nội dung mail thông qua trình duyệt Web với giao thức HTTP của Internet. ­ Phần mail server : thực hiện được chức năng tiếp nhận mail do trình khách (mail client) gửi lên (SMTP Server), lưu trữ mail trong thư mục nhất định cho phép người dùng sử dụng giao thức POP3 đọc mail (POP3 Server), chuyển mail đến máy chủ khác (Forward Server) hoặc phân giải địa chỉ mail gửi thẳng đến đích (Relay Server). 1.2.3.Dữ liệu vào, dữ liệu ra và các chức năng xử lý của hệ thống * Dữ liệu vào : ­ Phần mail client : + Thông tin đăng ký của người dùng ­ Phần mail server : + Mail do trình khách gửi lên + Thông tin về vị trí thư mục lưu trữ mail trên server * Dữ liệu ra : ­ Phần mail client : + Thông tin về tài khoản thư điện tử của người dùng. + Thư mục tương ứng với tên tài khoản, thông tin về user name và password để dùng cho việc POP3 Server chứng thực quyền truy cập của người dùng khi cần đọc mail ­ Phần mail server : + Lưu trữ mail do trình khách gửi đến + Chuyển tiếp những mail không thuộc domain mail do mail server quản lý. 1.2.4. Chức năng của hệ thống thông tin quản lý * Quản lý toàn bộ thông tin liên quan đến user như: họ, tên, ngày tháng năm sinh, nghề nghiệp, giới tính, quốc gia, thành phố… * Quản lý sổ địa chỉ 1.3. LÝ DO CHỌN ĐỀ TÀI Ngày nay đối với mỗi chúng ta thư điện tử không có gì xa lạ tuy nhiên đó là đứng về phương diện người dùng. Xuất phát từ mong muốn tìm hiểu một cách tường tận hơn hệ thống thư điện tử nhìn từ khía cạnh nhà thiết kế nên tôi đã quyết định chọn đề tài xây dựng ứng dụng thư điện tử theo mô hình Client Server. CHƯƠNG 2 : THIẾT KẾ VÀ CÀI ĐẶT ỨNG DỤNG 2.1.PHÂN TÍCH VÀ THẾT KẾ CƠ SỞ DỮ LIỆU 2.1.1.Phân tích Cơ sở dữ liệu được thiết kế đơn giản và dùng vào mục đích quản lý danh sách thành viên đăng ký sử dụng dịch vụ thư điện tử của vietmail. Với mục đích đó CSDL chỉ bao gồm hai thực thể chính là được thể hiện trong bảng sau : STT Tên thực thể Thuộc tính 1 members (thành viên) userid (mã thành viên ), user_name (tên đăng nhập), password (mật khẩu), question (câu hỏi), answer (câu trả lời), ho (họ), ten (tên), ngay (ngày sinh), thang (tháng sinh), nam (năm sinh), gioi_tinh (giới tính) nuoc (quốc gia), thanh_pho (thành phố), thanh_pho_khac (thành phố không thuộc Việt Nam), job (nghề nghiệp), thong_tin_khac (thông tin phụ khác), date(ngày đăng ký) 2 addressbook (Sổ địa chhỉ) addressid (mã sổ địa chỉ), userid (mã thành viên), quickname (tên gợi nhớ), ho (họ), ten (tên), email (địa chỉ email), phone (số điện thoại), diachi (địa chỉ) CÁC LƯỢC ĐỒ QUAN HỆ Từ những thực thể và thực thể trung gian trên, bằng các nguyên tắc biến đổi, ta xây dựng thành các lược đồ quan hệ như sau: Member (userid, user_name, password, question, answer, ho, ten, ngay, thang, nam, gioi_tinh, nuoc, thanh_pho, thanh_pho_khac, job, thong_tin_khac, date) Addressbook (addressid, userid, quickname,ho,ten,email,phone,diachi) Lược đồ quan hệ dữ liệu Phân tích chức năng Sơ đồ biểu diễn chức năng của hệ thống 2.1.2. Giải thích các chức năng của hệ thống ­ chức năng : Đăng ký thành viên Hệ thống quản lý thành viên của vietmail Đăng ký thành viên Quản lý sổ địa chỉ member userid user_name password question answer ho ten ngay thang nam gioi_tinh nuoc thanh_pho thanh_pho_khac job thong_tin_khac date addressbook addressid userid quickname ho ten email phone diachi ý nghĩa : thu thập các thông tin của thành viên nhằm mục đích quản lý cũng như thiết lập các thông số phục vụ cho việc gởi và nhận thư điện tử của thành viên ­ chức năng : Quản lý sổ địa chỉ ý nghĩa : tạo một danh sách boa gồm các địa chỉ do thành viên tự tạo rong quá trình sử dụng hệ thống. 2.1.3.biểu đồ luồng dữ liệu( DFD – Data flow Diagram) .Biểu đồ luồng dữ liêu mức khung cảnh (BFD) 2.1.4. THIẾT KẾ HỆ THỐNG 2.1.4.1. Các bảng dữ liệu chính Ký hiệu: PK: Khoá chính (Primary Key) FK: Khoá ngoại (Foreign Key) Bảng dữ liệu: Member ( Thành viên) Yêu cầu Thành viên Đăng ký Thông báo Hệ thống vietmail Tên trường Kiểu DL Độ lớn Ràng buộc Khoá Ghi chú userid int 4 Not Null PK user_name varchar 20 Not Null Tên đăng nhập password char 10 Mật khẩu question text 16 answer text 16 ho text 16 Not Null ten text 16 Not Null ngay smallint 2 Not Null thang smallint 2 Not Null nam int 4 Not Null gioitinh char 5 Not Null nuoc text Not Null thanh_pho text 16 Not Null thanh_pho_k hac text 16 job int 4 thong_tin_k hac text 16 date datetime 8 Not Null Bảngdữ liệu : Addresbook (sổ địa chỉ) Tên trường Kiểu DL Độ lớn Ràng buộc Khoá Ghi chú addressid int 7 Not Null PK userid int 8 Not Null Fk quickname text 8 ho text 8 ten text 20 email text Not Null phone text diachi text 2.2. CÀI ĐẶT MAILSERVER 2.2.1.Phương án tổ chức lưu trữ mail trên Server Để lưu trữ mail gửi đến trên server, mỗi trình mailserver sẽ có một phương án riêng để lưu trữ. Chẳng hạn có thể lưu trữ thông điệp mail như là các record trong bảng dữ liệu của database hoặc lưu trong cùng một file text phân cách mỗi thông điệp bằng một dấu hiệu đặc trưng nào đó. Tuy nhiên việc lưu thông điệp mail dưới dạng các file trong từng thư mục tương ứng của các User tỏ ra đơn giản hơn và cũng không kém phần hiệu quả. Vì vậy trong đồ án này tôi quyết định chọn phương án lưu thông điệp mail dưới dạng tập tin trên đĩa cục bộ. Trước khi cài đặt các đơn thể Mail server ta cần tổ chức thư mục để SMTP server lưu trữ mail như sau: Hình : Tổ chức thư mục lưu trữ mail Mỗi mailserver có thể có nhiều tên domain cho địa chỉ mail, các tên domain này được tổ chức trong 1 thư mục, ở đây ta chọn vietmail.com là tên domain mail. Lúc này một địa chỉ e – mail hợp lệ gửi đến SMTP server của ta phải có dạng như sau username@vietmail.com. Hệ thống mail server còn cho phép mở rộng thêm vào các domain mail khác. Danh sách các tên domain main nằm trong file domain.txt. Trong thư mục email\data\vietmail.com chứa danh sách các thư mục con đại diện cho từng tài khoản (như thanhboeing, xuanthu…). Thông tin đăng nhập của tài khoản được đặt trong file User.txt. 2.2.2.Các đơn thể của mailserver Trình MailServer có các đơn thể được cài đặt bằng ngôn ngữ java và bao gồm các phần chính sau: ­ Đơn thể xử lý tập lệnh SMTP ­ Đơn thể xử lý tập lệnh POP3 2.2.2.1. Xây dựng SMTP Server Nhiệm vụchính của SMTP Server là sử lý tập lệnh SMTP, trả lại mã lỗi do trình khách gởi lên không hợp lệ. Tiếp nhận dữ liệu và lưu vào thư mục nhất định để trình chủ POP3 Server có thể truy xuất sau này. SMTP server sẽ mở socket lắng nghe trên cổng 25 (cổng mặc định của SMTP). Ta cũng có thể thay đổi số hiệu cổng trong file cấu hình email.properties. khi nhận được kết nối từ trình khách, SMTP server sẽ mở một tuyến (thread) là lớp SMTPConection chịu trách nhiệm phân tích các lệnh SMTP và nhận mail do trình khách gởi lên. Lớp SMTP được cài đặt như sau: SMTPServer.java import java.io.*; import java.net.*; import java.util.*; public class SMTPServer extends Thread { protected ServerSocket listenSocket = null; protected Vector connections; public Boolean stopRequested; public SMTPServer() throws Exception { int port = 0; String portString = null; // Lấy số hiệu cổng S MTP từ file cấu hình try { portString = Server.properties.getProperty("smtp.port"); port = Integer.parseInt(portString); } catch (NumberFormatException e) { throw new Exception("Invalid 'smtp.port' ­ " + portString); } // Mở socket láng nghe kết nối từ trình khách listenSocket = new ServerSocket(port); // Mảng lưu các kết nối từ trình khách connections = new Vector(10, 10); } public void removeConnection(SMTPConnection connection) { connections.removeElement(connection); } public void run() { // Lặp vô tận chờ nhận kết nối cho đến khi có tín hiệu dừng stopRequested = new Boolean(false); while (true) { synchronized (stopRequested) { if (stopRequested.booleanValue()) break; } // chấp nhận kết nối try { Socket s = listenSocket.accept(); System.out.println("Accept"); //Phân tích các lệnh SMTP của trình khách – thực hiện việc tiếp nhận mail SMTPConnection connection = new SMTPConnection(s, this); connections.addElement(connection); connection.start(); } catch (IOException e) { e.printStackTrace(); break; } } // Đóng kết nối try { listenSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } Lớp SMTPConnection đóng vai trò chính trong SMTPServer. SMTPConnection phân tích các lệnh SMTP, nhận mail và lưu và thư mục tương ứng với địa chỉ mail của User. Chương trình mailserver cũng cho phép khả năng relayvà chuyển tiếp mail. Các mail có địa chỉ không thuộc domain do mailserver quản lý sẽ được lưu và thư mục queue (hay hàng đợi). Chương trình SMTPRelayServer và SMTPRForrwardServer sẽ xử lý các mail này. Lớp SMTPConnection được cài đặt như sau: SMTPConnection.java import java.io.*; import java.net.*; import java.util.*; /** * SMTPConnection : Xử lý các lệnh SMTP, lưu mail vào thư mục thích hợp */ public class SMTPConnection extends Thread { protected SMTPServer server; protected Socket socket; protected Vector recipients; public BufferedReader in; public PrintStream out; public String returnPath; protected Vector users; protected boolean stopRequested; public SMTPConnection(Socket socket, SMTPServer server) { this.socket = socket; this.server = server; } /** * Đóng kết nối – hoàn tất quá trình nhận mail từ trình khách * */ public void close() { try { socket.close(); } catch (Exception e) { System.err.println("Exception trying to close SMTPConnection socket!"); e.printStackTrace(System.err); } } /** * Xử lý lệnh SMTP DATA */ public void processDATA() throws IOException { String line; StringBuffer data = new StringBuffer(); line = in.readLine(); while (!line.equals(".")) { if (line.startsWith("..")) line = line.substring(1); // Đặt chuỗi nhận được vào StringBuffer System.out.println(line); data.append(line + "\n"); line = in.readLine(); } // Lưu thông điệp String messageId = Server.storage.saveMessage(users, data); // Thông báo cho trình khách thông điệp đã được lưu out.println("250 Message '" + messageId + "' accepted for delivery"); } /** * Xử lý lệnh SMTP EHELO – Lệnh này chỉ dành cho tập lệnh của SMTP mở rộng – nó tương ứng với lệnh bắt tay HELO **/ public void processEHLOCommand(StringTokenizer arguments) { processHELOCommand(arguments); } /** * Xử lý lệnh SMTP HELO **/ public void processHELOCommand(StringTokenizer arguments) { if (!arguments.hasMoreTokens()) { out.println("501 HELO requires domain address"); return; } out.println("250 " + Server.getAddress() + " Hello"); } /** * Xử lý lệnh SMTP MAIL **/ public boolean processMAIL() throws IOException { String line = ""; while (true) { line = in.readLine(); System.out.println(line); if (line.length() < 4) { out.println("500 Command Unknown '" + line + "'"); continue; } StringTokenizer tokenizer = new StringTokenizer(line); String command = tokenizer.nextToken(); if (command.equalsIgnoreCase("HELO")) { processHELOCommand(tokenizer); continue; } if (command.equalsIgnoreCase("EHLO")) { processEHLOCommand(tokenizer); continue; } if (command.equalsIgnoreCase("VRFY")) { processVRFYCommand(tokenizer); continue; } if (command.equalsIgnoreCase("QUIT")) { processQUITCommand(tokenizer); return false; } if(command.equalsIgnoreCase("RCPT")||command.equalsIgnoreCase("DATA" )) { out.println("503 Bad sequence of commands ­ specify MAIL first"); continue; } if (command.equalsIgnoreCase("MAIL")) { if (processMAILCommand(tokenizer)) { out.println("250 OK"); return true; } } out.println("500 Command Unknown '" + line + "'"); } } public boolean processMAILCommand(StringTokenizer arguments) { if (!arguments.hasMoreTokens()) { out.println("503 Syntax: MAIL FROM:"); return false; } returnPath = arguments.nextToken(); System.out.println(returnPath+" "+returnPath.length()); if (returnPath.length() < 5) { out.println("503 Syntax: MAIL FROM:"); return false; } if (!returnPath.substring(0, 5).equalsIgnoreCase("FROM:")) { out.println("503 Syntax: MAIL FROM:"); return false; } return true; } protected void processQUITCommand(StringTokenizer arguments) { out.println("221 " + Server.getAddress() + " closing connection"); stopRequested = true; } public boolean processRCPT() throws IOException { users = new Vector(2, 2); String line = ""; while (true) { line = in.readLine(); System.out.println(line); if (line.length() < 4) { out.println("500 Command Unknown '" + line + "'"); continue; } StringTokenizer tokenizer = new StringTokenizer(line); String command = tokenizer.nextToken(); if (command.equalsIgnoreCase("EHLO")) { processEHLOCommand(tokenizer); continue; } if (command.equalsIgnoreCase("VRFY")) { processVRFYCommand(tokenizer); continue; } if (command.equalsIgnoreCase("RSET")) { out.println("250 Reset state"); return false; } if (command.equalsIgnoreCase("QUIT")) { processQUITCommand(tokenizer); return false; } if (command.equalsIgnoreCase("MAIL")) { out.println("503 Sender already specified"); continue; } if (command.equalsIgnoreCase("DATA")) { if (users.size() == 0) { out.println("503 Bad sequence of commands ­ specify RCPT first"); continue; } out.println("354 Enter mail, ending with '.' on a line by itself"); return true; } if (command.equalsIgnoreCase("RCPT")) { processRCPTCommand(tokenizer); continue; } out.println("500 Command Unknown '" + line + "'"); } } public void processRCPTCommand(StringTokenizer arguments) { if (!arguments.hasMoreTokens()) { out.println("501 Syntax: RCPT TO:"); return; } String arg = arguments.nextToken(); if (!arg.substring(0, 3).equalsIgnoreCase("TO:")) { out.println("501 Syntax: RCPT TO:"); return; } // Địa chỉ nằm sau "TO:" System.out.println(arg); // Một vài trình khách gởi lệnh RCPT TO: không có khoảng trắng sau TO String address; try{ address=arguments.nextToken(); //có khoảng trắng } catch(Exception e){ address = arg.substring(3);//không có khoảng trắng } System.out.println("Receipt address :"+address); // Thông thường địa chỉ mail được gởi theo dạng if (address.substring(0, 1).equals("<") && address.substring(address.length() ­ 1, address.length()).equals(">")) address = address.substring(1, address.length() ­ 1); // Lấy về thông tin của user từ địa chỉ mail User user = Server.storage.getUser(address); // Báo lỗi cho trình khách nếu user không tồn tại if (user == null) { out.println("550 User " + address + " is not known"); return; } // Đưa user vào danh sách phân phối mail users.addElement(user); // Trả về mã lỗi thành công out.println("250 Recipient " + address + " ok"); } public void processVRFYCommand(StringTokenizer arguments) { out.println("252 VRFY command not implemented"); } /** * Phương thức run() lặp liên tục để ­ lý lệnh cho đến khi hoàn tất */ public void run() { try { in=new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintStream(socket.getOutputStream()); } catch (IOException e) { e.printStackTrace(System.err); close(); return; } stopRequested = false; out.println("220mail.goemaat.comJAVASMTPServer (com.goemaat.email.SMTP) ready"); while (!stopRequested) { try { if (processMAIL()) { if (processRCPT()) processDATA(); } } catch (IOException e) { e.printStackTrace(System.err); stopRequested = true; } } // Đóng socket đã mở trước đó close(); // Loại bỏ kết nối trong danh sách SMTPServer server.removeConnection(this); } } Chương trình Server.java dưới đây được dùng để đọc file cấu hình email.properties, khởi tạo SMTPServer. Server.java cũng làm nhiệm vụ khởi tạo trình chủ POPServer. Trình Server.java được cài đặt như sau: Server.java import java.io.*; import java.util.*; public class Server { public static Properties properties; public static SMTPServer smtp; public static EmailStorage storage; public static POPServer pop; public static String getAddress() { String address = properties.getProperty("server.address"); if (address == null) address = "UNKNOWN[server.address]"; return address; } protected static boolean getProperties() { try { String fileName = "email.properties"; // Kiểm tra sự tồn tại của file cấu hình email.properties File file = new File(fileName); if (!file.exists()) { fileName = file.getAbsolutePath(); System.out.println("Specified properties file '" + file.getAbsolutePath() + "' does not exist!"); return false; } // Đọc các thông tin cấu hình properties = new Properties(); FileInputStream in = new FileInputStream(file); properties.load(in); in.close(); } catch (Exception e) { System.out.println(e); return false; } System.getProperties().put("line.separator", "\r\n"); return true; } /** * Chương trình chính */ public static void main(String[] args) { if (!getProperties()) { System.err.println("Could not get properties!"); return; } System.out.println(Server.properties.getProperty("smtp.port")); // Thiết lập nơi lưu trữ mail if (!setupStorage()) { System.out.println("Could not setup storage!"); return; } // Khởi tạo SMTP server if (!startSMTPServer()) { System.err.println("Could not start SMTP server!"); return; } // Khởi tạo POP server if (!startPOPServer()) { System.err.println("Could not start POP server!"); return; } } /** *Phương thức khởi tạo nơi lưu trữ mail */ public static boolean setupStorage() { String className = properties.getProperty("storage.class"); if (className == null || className.length() == 0) { System.err.println("No storage class specified in property 'storage.class'!"); return false; } Class c = null; try { c = Class.forName(className); } catch (ClassNotFoundException e) { System.err.println("Class '" + className + "' not found! (check CLASSPATH)"); e.printStackTrace(System.err); return false; } // Tạo thể hiện của lớp try { storage = (EmailStorage)c.newInstance(); } catch (InstantiationException e) { e.printStackTrace(System.err); return false; } catch (IllegalAccessException e) { e.printStackTrace(System.err); return false; } return storage.init(); } /** * Khởi tạo POP server. */ protected static boolean startPOPServer() { try { pop = new POPServer(); pop.setDaemon(false); pop.start(); } catch (Exception e) { e.printStackTrace(System.err); return false; } return true; } /** * Khởi tạo SMTP server. */ protected static boolean startSMTPServer() { try { smtp = new SMTPServer(); smtp.setDaemon(false); smtp.start(); } catch (Exception e) { e.printStackTrace(System.err); return false; } return true; } } 2.2.2.2. Xây dựng POP3 Server Trình POP3 Server gồm hai phần, phần POPServer chịu trách nhiệm mở socket và lắng nghe kết nối từ trình khách gởi lên theo cổng 110 (cổng mặc định của giao thức POP3). Khi nhận được kết nối, POPServer yêu cầu lớp PÔPCnnection phân tích các lệnh của giao thức POP3 và gởi mail về cho trình khách. Lớp POP3 được cài đặt như sau: POPServer.java import java.io.*; import java.net.*; import java.util.*; public class POPServer extends Thread { public Vector connections; public Boolean stopRequested; protected ServerSocket listenSocket; public POPServer() throws Exception { int port = 0; String portString = null; // Lấy só hiệu cổng từ file cấu hình try { portString = Server.properties.getProperty("pop.port"); port = Integer.parseInt(portString); } catch (NumberFormatException e) { throw new Exception("Invalid 'pop.port' ­ " + portString); } // Lắng nghe trên socket sự kết nối từ trình khách listenSocket = new ServerSocket(port); // Tạo mảng chứa danh sách các kết nối connections = new Vector(10, 10); } public void removeConnection(POPConnection connection) { } /** * Xử lý kết nối */ public void run() { // Lặp vô tận cho đến khi có yêu cầu dừng stopRequested = new Boolean(false); while (true) { synchronized (stopRequested) { if (stopRequested.booleanValue()) break; } // Chấp nhận kết nối do trình khách gởi lên try { Socket s = listenSocket.accept(); //Yêu cầu lớp POPConnection xử lý giao thức phục vụ trình khách POPConnection connection = new POPConnection(s, this); connections.addElement(connection); connection.setDaemon(true); connection.start(); } catch (IOException e) { e.printStackTrace(); break; } } // Đóng kết nối try { listenSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } Lớp POPConnection.java chịu trách nhiệm chính trong việc xử lý các lệnh của giao thức POP3. Lớp POPConnection được cài đặt như sau : POPConnection.java import java.io.*; import java.net.*; import java.util.*; public class POPConnection extends Thread { protected static final int ENTER_USER = 0; protected static final int ENTER_PASSWORD = 1; protected static final int TRANSACTION = 2; protected static final int UPDATE = 3; protected POPServer server; protected Socket socket; protected BufferedReader in; protected PrintStream out; protected boolean stopRequested; protected int state; protected String userName; protected User user; protected Vector messages = null; public POPConnection(Socket socket, POPServer server) { super(); this.socket = socket; this.server = server; } protected void close() { try { socket.close(); } catch (Exception e) { System.err.println("Exception trying to close POPConnection socket!"); e.printStackTrace(System.err); } } // Đếm số mail có trong hộp thư protected int countMessages() { if (messages == null) return 0; Enumeration enum = messages.elements(); int count = 0; while (enum.hasMoreElements()) { Message message = (Message)enum.nextElement(); if (!message.isDeleted()) count++; } return count; } /** * Lấy nội dung mail dựa vào số thứ tự của mail lưu trong hộp thư */ protected Message getMessage(int number) { if (number messages.size()) return null; Message message = (Message)messages.elementAt(number ­ 1); if (message.isDeleted()) return null; return message; } protected Message getMessage(String messageNumber) { int number; try { number = Integer.parseInt(messageNumber); } catch (NumberFormatException e) { return null; } return getMessage(number); } protected long getMessagesSize() { if (messages == null) return 0; Enumeration enum = messages.elements(); long size = 0; while (enum.hasMoreElements()) { Message message = (Message)enum.nextElement(); if (!message.isDeleted()) size += message.getSize(); } return size; } protected void processDELE(StringTokenizer arguments) { if (!arguments.hasMoreTokens()) { out.println("­ERR must supply message number"); } else { Message message = getMessage(arguments.nextToken()); if (message == null) { out.println("­ERR no such message"); } message.setDeleted(true); out.println("+OK"); } } /** * Xử lý lệnh PASS kiểm tra password */ protected void processEnterPassword(String command, StringTokenizer arguments) { if (command.equalsIgnoreCase("QUIT")) { stopRequested = true; out.println("+OK Signing off"); } else if (command.equalsIgnoreCase("PASS")) { if (!arguments.hasMoreTokens()) { out.println("­ERR must supply password"); return; } String password = arguments.nextToken(); if (arguments.hasMoreTokens()) { out.println("­ERR only one argument to PASS, your password"); return; } // Kiểm tra quyền đăng nhập user = Server.storage.login(userName, password); if (user == null) { out.println("­ERR invalid user or password"); state = ENTER_USER; } else { // user đã đăng nhập – trả về danh sách các mail có trong hộp thư messages = Server.storage.getMessages(user); out.println("+OK mailbox open, " + countMessages() + " messages"); state = TRANSACTION; } } else { out.println("­ERR Only use PASS or QUIT commands"); } } /** * Xử lý lệnh USER */ protected void processEnterUser(String command, StringTokenizer arguments) { if (command.equalsIgnoreCase("QUIT")) { stopRequested = true; out.println("+OK Signing off"); return; } if (command.equalsIgnoreCase("USER")) { if (!arguments.hasMoreTokens()) { out.println("­ERR must supply user name"); return; } userName = arguments.nextToken(); if (arguments.hasMoreTokens()) { out.println("­ERR only one argument to USER, the user name"); return; } state = ENTER_PASSWORD; out.println("+OK use PASS command to send password"); return; } out.println("­ERR Only use USER or QUIT commands"); } /** * Xử lý lệnh LIST */ protected void processLIST(StringTokenizer arguments) { if (!arguments.hasMoreTokens()) { out.println("+OK " + countMessages() + " " + getMessagesSize()); for (int i = 1; i <= messages.size(); i++) { Message message = getMessage(i); if (message != null) { out.println(i + " " + message.getSize()); } } out.println("."); } else { String messageNumber = arguments.nextToken(); Message message = getMessage(messageNumber); if (message == null) { out.println("­ERR no such message"); } else { out.println("+OK " + messageNumber + " " + message.getSize()); } } } /** * Xử lý lệnh NOOP – Lệnh NOOP của POP3 không làm gì cả, mục đích chỉ để trình khách xem kết nối còn hiệu lực hay không */ protected void processNOOP(StringTokenizer arguments) { out.println("+OK"); } /** * Xử lý lệnh QUIT */ protected void processQUIT(StringTokenizer arguments) { Enumeration enum = messages.elements(); while (enum.hasMoreElements()) { Message message = (Message)enum.nextElement(); if (message.isDeleted()) { Server.storage.deleteMessage(message); } } out.println("+OK Goodbye, " + user.getName()); stopRequested = true; } /** * Xử lý lệnh RETR trả về nội dung mail */ protected void processRETR(StringTokenizer arguments) { if (!arguments.hasMoreTokens()) { out.println("­ERR message number required, RETR 1"); } else { String messageNumber = arguments.nextToken(); Message message = getMessage(messageNumber); if (message == null) { out.println("­ERR no such message"); return; } out.println("+OK " + message.getSize() + " octets"); // Đọc dữ liệu mail StringBuffer buffer = Server.storage.getMessageData(message); BufferedReader reader = new BufferedReader(new StringReader(buffer.toString())); // Đọc từng dòng boolean done = false; try { while (reader.ready() && (!done)) { String line = reader.readLine(); if (line == null) break; // Dấu chấm kết thúc if (line.length() >= 1) { if (line.substring(0, 1).equals(".")) line = "." + line; } // Gửi dữ liệu về trình khách out.println(line); } } catch (IOException e) { System.err.println("POPConnection.processRETR()"); e.printStackTrace(System.err); } try { reader.close(); } catch (IOException e) { System.err.println("POPConnection.processRETR() ­ reader.close()"); e.printStackTrace(System.err); } out.println("."); } } /** * Xử lý lệnh RSET */ protected void processRSET(StringTokenizer arguments) { Enumeration enum = messages.elements(); while (enum.hasMoreElements()) { Message message = (Message)enum.nextElement(); if (message.isDeleted()) message.setDeleted(false); } out.println("+OK"); } /** * Xử lý lệnh STAT */ protected void processSTAT(StringTokenizer arguments) { out.println("+OK " + countMessages() + " " + getMessagesSize()); } /** * Xử lý lệnh TOP – trả về trình khách các mail header */ protected void processTOP(StringTokenizer arguments) { if (!arguments.hasMoreTokens()) { out.println("­ERR syntax: TOP "); return; } String messageNumber = arguments.nextToken(); if (!arguments.hasMoreTokens()) { out.println("­ERR syntax: TOP "); return; } int lines = 0; try { lines = Integer.parseInt(arguments.nextToken()); } catch (NumberFormatException e) { out.println("­ERR bad number of lines"); return; } Message message = getMessage(messageNumber); if (message == null) { out.println("­ERR no such message"); return; } out.println("+OK " + message.getSize() + " octets"); StringBuffer buffer = Server.storage.getMessageData(message); BufferedReader reader = new BufferedReader(new StringReader(buffer.toString())); boolean done = false; boolean inBody = false; int count = 0; try { while (reader.ready() && (!done) && (count <= lines)) { String line = reader.readLine(); if (line == null) break; if (line.length() >= 1) { if (line.substring(0, 1).equals(".")) line = "." + line; } else { inBody = true; } if (inBody) { count++; } out.println(line); } } catch (IOException e) { System.err.println("POPConnection.processTOP()"); e.printStackTrace(System.err); } try { reader.close(); } catch (IOException e) { System.err.println("POPConnection.processTOP() ­ reader.close()"); e.printStackTrace(System.err); } out.println("."); } /** * Xử lý các lệnh của giao thức POP3 */ protected void processTransaction(String command, StringTokenizer arguments) { if (command.equalsIgnoreCase("STAT")) { processSTAT(arguments); } else if (command.equalsIgnoreCase("LIST")) { processLIST(arguments); } else if (command.equalsIgnoreCase("RETR")) { processRETR(arguments); } else if (command.equalsIgnoreCase("DELE")) { processDELE(arguments); } else if (command.equalsIgnoreCase("NOOP")) { processTOP(arguments); } else if (command.equalsIgnoreCase("TOP")) { processTOP(arguments); } else if (command.equalsIgnoreCase("UIDL")) { processUIDL(arguments); } else if (command.equalsIgnoreCase("RSET")) { processRSET(arguments); } else if (command.equalsIgnoreCase("QUIT")) { processQUIT(arguments); } else { out.println("­ERR Unknown command " + command); } } protected void processUIDL(StringTokenizer arguments) { if (!arguments.hasMoreTokens()) { out.println("+OK " + countMessages() + " " + getMessagesSize()); for (int i = 1; i <= messages.size(); i++) { Message message = getMessage(i); if (message != null) { out.println(i + " " + message.getMessageId()); } } out.println("."); } else { String messageNumber = arguments.nextToken(); Message message = getMessage(messageNumber); if (message == null) { out.println("­ERR no such message"); } else { out.println("+OK " + messageNumber + " " + message.getMessageId()); } } } /** * Nhận kết nối và các lệnh POP3 gửi lên từ trình khách */ public void run() { try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintStream(socket.getOutputStream()); } catch (IOException e) { e.printStackTrace(System.err); close(); return; } if (server == null) { System.err.println("SERVER NOT SET!!!"); return; } stopRequested = false; state = ENTER_USER; out.println("+OK POP3 " + Server.getAddress()); while (!stopRequested) { try { String line = in.readLine(); if (line == null) break; StringTokenizer tokenizer = new StringTokenizer(line); String command = ""; if (tokenizer.hasMoreTokens()) command = tokenizer.nextToken(); // Xử lý lệnh tuỳ theo trạng thái đăng nhập của user switch (state) { case ENTER_USER: processEnterUser(command, tokenizer); break; case ENTER_PASSWORD: processEnterPassword(command, tokenizer); break; case TRANSACTION: processTransaction(command, tokenizer); break; default: out.println("­ERR invalid state! "); System.err.println("Invalid State in POPConnection.run()"); stopRequested = true; break; } } catch (Exception e) { e.printStackTrace(System.err); stopRequested = true; } } // Đóng kết nối close(); server.removeConnection(this); } public void setServer(POPServer server) {} } 2.3.CÀI ĐẶT MAILCLIENT Cấu trúc của Website Phần MailClient được thiết kế dưới dạng Web dùng Java Server Page nên được gọi là một WebMail. Trang Web và quá trình sử dụng mailclient có thể được hình dung qua sơ đồ và đặc tả đưới đây 1.Đăng nhập hệ thống : HomePage Đăng Ký Thành Viên Login Help Menumail Inbox AddressBook Option Add Edit Review Inf Change Password Hình cấu trúc Website Lần đầu tiên sử dụng CT để gửi nhận mail, chúng ta phải đăng ký một account mới cho riêng mình, nghĩa là chúng ta phải có một username và password riêng cho mình nhằm phân biệt những người sử dụng email khác nhau và bảo mật thư của từng người. _ Đăng nhập username và password trước khi vào hệ thống . Nếu là “member”: bạn có thể sử dụng CT gửi /nhận thư . Nếu là “guest”: bạn phải Đăng ký thành viên 2.Đăng ký thành viên : Cho lần đầu tiên bạn đăng nhập vào hệ thống , ghi các thông tin cá nhân, username và password của bạn. 3.Các loại Address Book . Điều chỉnh thông tin trong Personal Address Book : (User có quyền T, X, S addressbook của mình) Các thông tin về địa chỉ mail của các Client được lưu trữ trong các sổ địa chỉ. Mỗi người sử dụng mail thường có một sổ địa chỉ cá nhân (Personal Address Book ­ PAB) của riêng mình và được lưu trữ trong ổ đĩa cục bộ . Các thông tin cần thiết khi thêm một địa chỉ E­mail vào PAB: _ RealName là họ tên đầy đủ của người có địa chỉ mail cần thêm vào PAB _ E­mail Address địa chỉ E­mail chính xác của người cần thêm vào. Ngoài ra, chúng ta có thể thêm vào những địa chỉ email khác, số phone, mobile và địa chỉ nhà riêng 4.Review Account Information: _ User xem lai thông tin cá nhân đã đăng nhập và AddressBook của mình. _ Có thể thay đổi Password (changepassword.asp) khi bạn muốn đặt lại một password mới cho mình. 5.Thay đổi Pass : _ Old Password: nhập lại pass hiện tại. _ New password: nhập pass mới. Bạn có thể sử dụng các ký tự chữ, số và cả hệ thống chấm câu, nhưng không thể sử dụng khoảng trắng. _ Nhập lại password một lần nữa. Nếu so trùng, việc thay đổi password xem như thành công. 6.Kiểm tra thư: Vùng nội dung các Folder sẽ xuất hiện tiêu đề các thư trong folder đó. Các thư chưa được đọc thường được trình bày khác với thư đã được đọc. Thông thường phần tiêu đềthư gồm các nội dung như sau: _ From: Tên người gửi, nội dung xuất hiện ở đây không phải là địa chỉ e­mail của người gửi mà là họ tên của người gửi. _ Subject : Chủ đề của lá thư . Khi gửi thư, ngưòi gửi thường ghi một nội dung ngắn vào vùng subject để người nhận biết được mục đích tổng quát của lá thư trước khi quyết định có đọc thư hay không. _ Date : Ngày giờ nhận thư _ Size: Kích thước lá thư (thường tính bằng KB) 7.Đọc thư : INBOX CheckMail Upload File Compose Read Reply Delete DownLoad Send Error Ok Tất cả thư của bạn được liệt kê trong một bảng trong Inbox với mỗi hàng là một thư. Để xem nội dung thư cần click vào vùng tiêu đề của thư. Trong vùng nội dung thư, các thông tin của ngưòi gửi sẽ được thể hiện cùng nội dung lá thư . Các thông tin người gửi bao gồm: tên người gửi, thời điểm gửi, tên người nhận Muốn đọc email nào, click vào cột From tương ứng. Sau khi đọc xong, để đọc thư khác, click vào Inbox hay click vào nút Back của Internet Explorer. _ Sau khi đọc xong thư ,Delete nếu muốn xóa thư. _ Reply nếu muốn trả lời thư _ Download attach file nếu thư có gửi file kèm theo . 8.Viết email trong WebMail: Chúng ta có hai trường hợp:  Nếu bạn đang đọc một thư nào đó, bạn muốn trả lời thư đóthì click vào nút Reply phía trên.  Nếu bạn muốn gửi thư trực tiếp, click vào nút Compose. Khi muốn gửi thư cho một người đã có địa chỉ trong một AddressBook, đầu tiên phải chuẩn bị nội dung thư để gửi. Phần tiêu đề của một thư cần gửi bao gồm các thông tin sau: _ To : Địa chỉ email mà bạn muốn gửi tới. _ Subject: một đoạn text ngắn cho biết mục đích của nội dung thư cần gửi. Đoạn text này giúp cho người đọc thư quyết định có nên xem nội dung của thư hay không. _ Attachments gởi kèm tập tin cho nguười nhận. _ Nội dung soạn trong comment _ Sau khi soạn thảo nội dung thư xong, nhấn nút Send để thư được cất vào Outbox. Nghĩa là, thư không được truyền đi ngay, do đó chúng ta có thể soạn thảo nhiều thư trước khi kết nối với Mail Server để gửi đi. Khi thư đã đưa vào Outbox, mọi chỉnh sửa tiếp theo thường làm thư không gửi đi được nữa. Trường hợp này cần phải soạn thảo một lá thư khác để gửi đi và xóa bỏ lá thư cũ. 9.Gửi kèm file theo Mail (attach file) Trong một số trường hợp cần đưa thêm toàn bộ nội dung một tập tin đang có sẵn trên đĩa cục bộ vào thư để gửi đến ngưòi nhận. Công việc này được gọi là Attach file vào thư. Cần chú ý rằng việc attach một tập tin vào mail cần phải được thực hiện đồng bộ giữa người gửi , người nhận và đường truyền thư.Nếu không có sự đồng bộ, nội dung của tập tin được attach có người nhận không đọc được. Lý do của việc này là do nội dung của tập tin được attach sẽ được mã hoá theo UUENCODE hay theo MIME (Multipurpose Internet Mail Extensions). Thông thường để giảm thời gian truyền thư, các tập tin cần attach vào thư sẽ được nén trước khi thực hiện thao tác attach. Cách nén thông dụng là ZIP. Các tập tin được gửi kèm có thể lưu thành một tập tin riêng trong điã cục bộ của người sử dụng. Thông thường dung lượng tập tin gửi kèm không nên quá 1MB, nếu lớn hơn ta cần tách ra gửi nó trong nhiều thư. 10. Download / Upload file Một số giao diện chính Trang đăng nhập của vietmail Menu chính TÀI LIỆU THAM KHẢO  Phân tích, thiết kế và cài đặt hệ thống thông tin quản lý ­ Hiệu đính: GS. Bạch Hưng Khang  Cơ sở dữ liệu quan hệ ­ Lê Tấn Vương  System Administrator for Microsoft SQL Serever 7.0 workbook  Microsoft SQL Server 7.0 Database Implementation Training Kit  Microsoft SQL Server hoạch định và xây dựng cơ sở dữ liệu cao cấp  Allaire JRUN Developer Documentation  Enterprise JavaBeans – Tom Valesky  Enterprise JavaBeans by Example – Henri Jubin, Jurgen Friendichs  HTML by Example – Todd Stauffer  Special Edition Using HTML 4 – Jerry Honeycutt  Special Edition Using JavaScript – Mark C. Reynolds  Java by Example – Clayton Walnum  Lập trình Java thế nào? – Hoàng Ngọc Giao  Java lập trình mạng – Nguyễn Phương Lan, Hoàng Đức Hải  Các tài liệu về JSP/EJB tại website:

Các file đính kèm theo tài liệu này:

  • pdfĐồ án tốt nghiệp - Phân tích thiết kế hệ thống - Dịch vụ thư tín điện tử và cài đặt một chương trình mang tính thử nghiệm do dịch vụ thư tín điện tử.pdf