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).
151 trang |
Chia sẻ: lylyngoc | Lượt xem: 2519 | Lượt tải: 0
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ỉ Email vào PAB:
_ RealName là họ tên đầy đủ của người có địa chỉ mail cần thêm vào PAB
_ Email Address địa chỉ Email 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ỉ email
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:
- Đồ á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