THREAD trong DELPHI.doc

130 1.1K 10
THREAD trong DELPHI.doc

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

THREAD trong DELPHI

Trang 1

1 GIỚI THIỆU THREAD TRONG DELPHI 3

1.1 THREADLÀGÌ? 3

1.2 ỨNGDỤNGCỦA THREAD 3

1.3 SỬDỤNG TTHREADTRONG DELPHI 4

1.3.1 Các method đáng chú ý khi viết Thread 5

1.3.2 Các property đáng chú ý khi viết Thread 6

1.3.3 Tranh chấp dữ liệu khi viết multi-thread 7

1.3.4 Sử Dụng Critical Section trong chương trình 9

2 GIAO TIẾP GIỮA CÁC MÁY MÔ HÌNH CLIENT/SERVER 9

2.1 TCLIENTSOCKET 10

2.1.1 Ghi dữ liệu đến server 10

2.1.2 Đọc dữ liệu từ server 11

2.2 TCLIENTWINSOCKET 11

2.3 TSERVERSOCKET 12

2.3.1 Truyền dữ liệu đến một Client 13

2.3.2 Đọc dữ liệu từ một client 13

2.3.3 Bạn có thể biết chính xác Client thứ mấy đã gửi dữ liệu đến server socket 14

2.4 TSERVERWINSOCKET 14

2.4.1 Lắng nghe yêu cầu kết nối của Client 14

2.4.2 Quản lý dãy các client socket đã kết nối với server socket 15

2.5 TSERVERCLIENTWINSOCKET 15

3 GIỚI THIỆU CHƯƠNG TRÌNH 16

3.1 NỘIDUNGVÀÝNGHĨACHƯƠNGTRÌNH 16

3.2 CÁCVẤNĐỀCHÍNHCẦNGIẢIQUYẾT 20

3.2.1 Tổ chức dữ liệu trong chương trình 20

3.2.2 Kết nối cho client 21

3.2.3 Hủy kết nối cho client 22

3.2.4 Tranh chấp dữ liệu 22

3.2.5 Dùng thread để phân chia CPU cho các thao tác của client 22

3.3 CÁCCHỨCNĂNGCHONGƯỜIQUẢNLÝ 23

3.3.1 Tìm kiếm một nhà 24

3.3.2 Lấy thông tin của một nhà 25

3.3.3 Thêm thông tin một nhà mới 26

3.3.4 Xóa thông tin một nhà 28

3.3.5 Cập nhật thông tin một nhà 29

3.3.6 Thống kê số nhà đã cho thuê 31

3.3.6.1 Đếm số nhà đã cho thuê 31

3.3.6.2 Đưa một nhà đã hết hạn cho thuê về danh sách các nhà có thể cho thuê 32

3.3.7 Thống kê số nhà đã bán 36

3.3.7.1 Đếm số nhà đã bán 36

3.4 CÁCCHỨCNĂNGCHONGƯỜICẬPNHẬTTHÔNGTINNHÀ 37

3.4.1 Tìm kiếm một nhà 38

Trang 2

3.5 CÁCCHỨCNĂNGCHOMỘTKHÁCHHÀNG 40

3.5.1 Lấy thông tin về một nhà 40

3.5.2 Tìm kiếm một nhà 40

3.5.3 Tìm kiếm theo điều kiện 41

3.5.4 Đăng ký thuê nhàø 46

3.5.5 Đăng ký mua nhà 50

3.6 MÃCHƯƠNGTRÌNHKINHDOANHNHÀĐẤTTRÊNMẠNGCLIENT/SERVER 53

Trang 3

1 Giới thiệu Thread trong Delphi

1.1 Thread là gì?

Tính năng Thread cho phép một chương trình xử lý đồng thời nhiều công việc Chẳng hạn trong chương trình Go!Zilla Ver 3.2 Copyright  1997-98 Gizmonet, một lúc có thể download nhiều file từ cùng hoặc nhiều website khác nhau Nó còn cho người dùng định độ ưu tiên cho từng thread.

Bạn có thể dùng BorlandC, Delphi, Cbuilder, Visual C để viết nên những chương trình có tính năng thread Nhưng dù bạn lập trình bằng ngôn ngữ nào đi chăng nữa, thì cũng phải sử dụng những hàm API của Microsoft cung cấp như CreateThread,

SetThreadPriority một cách trực tiếp hoặc gián tiếp

1.2 Ứng dụng của Thread

Thread được sử dụng rất nhiều trên các lĩnh vực như đồ họa (xử lý nhiều hình ảnh một lúc), trong trò chơi (làm nền hoặc mỗi nhân vật trong trò chơi là một thread), truyền tin (tín hiệu xuất ra được xử lý tức thời)

Thread làm cho chương trình trở nên đơn giản, dễ hiểu khi ta phải viết những chương trình đòi hỏi xử lý đồng thời nhiều công việc.

Trang 4

1.3 Sử dụng TThread trong Delphi

Sử dụng TThread của Delphi để viết nên những chương trình có tính năng Thread thì rất dễ Cấu trúc cơ bản một unit có sử dụng Thread như sau :

Một điều quan trọng cần lưu ý khi viết Thread là những đối tượng hay hàm nào nằm

trong thư viện VCL của Delphi phải gọi bằng phương pháp Synchronize.

Ví dụ :

Trang 5

procedure TMyThread.UpdateCaption; begin

Form1.Caption := 'Updated in a thread'; end;

1.3.1 Các method đáng chú ý khi viết Thread* Constructor Create(CreateSuspended: Boolean);

Constructor Create để khởi tạo một đối tượng Thread

Nếu CreateSuspended = False, Execute được gọi ngay lập tức

Nều CreateSuspended = True, Execute không được gọi cho đến khi Resume được gọi.

* Destructor Destroy; override;

Destructor Destroy hủy đối tượng thread và giải phóng bộ nhớ nó chiếm giữ.

* Procedure DoTerminate; virtual;

DoTerminate làm cho thread gọi sự kiện OnTerminate.

* Procedure Execute; virtual; abstract;

Procedure Execute là một method abstract phải được override bởi lớp con Nó chứa mã khi bắt đầu Thread.

* Procedure Resume;

Procedure Resume tiếp tục gọi một thread tạm ngưng.

* Procedure Suspend;

Procedure Suspend tạm ngưng một thread đang chạy.

* Procedure Synchronize(Method: TThreadMethod);

Procedure Synchronize thực hiện method dùng thư viện VCL.

* Procedure Terminate;

Procedure Terminate ra hiệu cho thread dừng bằng cách gán property Terminated là True.

Trang 6

1.3.2 Các property đáng chú ý khi viết Thread* property FreeOnTerminate: Boolean;

property FreeOnTerminate định cho đối tượng thread tự động giải phóng nhớ nếu FreeOnTerminate = True.

* property Handle: Thandle;

property Handle là handle của thread.

* property Priority: TThreadPriority;

property Priority xác định độ ưu tiên giữa các thread khác trong tiến trình TThreadPriority = (tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, tpTimeCritical);

+ tpIdle : Chỉ thực hiện khi hệ thống Windows rảnh rỗi, nó không ngắt ngang đối tượng thread khác để chạy.

+ tpLowest : Mức độ ưu tiên dưới 2 điểm so với bình thường + tpLower : Mức độ ưu tiên dưới 1 điểm so với bình thường + tpNormal: Mức độ ưu tiên bình thường.

+ tpHigher : Mức độ ưu tiên trên 1 điểm so với bình thường + tpHigher : Mức độ ưu tiên trên 1 điểm so với bình thường + tpHighest : Mức độ ưu tiên trên 2 điểm so với bình thường + tpTimeCritical : Mức độ ưu tiên cao nhất.

* property Suspended: Boolean;

property Suspended chỉ định thread tạm ngưng nếu bằng true.

* property Terminated: Boolean;

property Terminated chỉ định rằng thread yêu cầu dừng nếu bằng true.

Trang 7

1.3.3 Tranh chấp dữ liệu khi viết multi-thread

Khi bạn viết một chương trình multi-threaded, có trường hợp 2 thread cùng truy cập đến một vùng dữ liệu, chẳng hạn như là một file, điều này có thể làm cho file bị hư hoặc có thể máy của bạn sẽ bị treo Để giải quyết vấn đề này, bạn sẽ cho các thread khác không thể truy cập đến vùng nhớ mà thread hiện hành đang sửa đổi dữ liệu cho đến khi dữ liệu được xử lý xong.

Critical sections được thiết kế mà một phần resource được dùng riêng biệt và tách rời khỏi các tiến trình khác Bạn hãy tưởng tượng rằng có hai người cùng đi song song trên một con đường, bỗng nhiên xuất hiện một cây cầu hẹp, chỉ đủ để một người đi qua Bình thường một người sẽ nhường đường cho người kia đi trước Khi mà một người qua cầu rồi thì người kia sẽ tiếp tục đi qua cầu và họ lại tiếp tục đi song song với nhau.

Critical sections cũng tương tự như việc đi qua cầu Bạn hãy nhìn hình ở trên đây, hai thread (mũi tên màu cyan) đang chạy trên tiến trình đơn (vùng màu đen), khi các thread chạy đến critical sections (vùng màu xanh dương), một thread sẽ nhường cho thread kia đi qua Trong thực tế, một thread sẽ đi đến critical sections, nó có thể tạo ra một cờ ra hiệu cho các thread khác không được liên lạc với data

Để thực hiện critacal sections trong mã chương trình viết bằng Borland Delphi, bạn hãy làm dấu khối trên mỗi thread mà truy cập đến vùng nhớ chung bằng các hàm

EnterCriticalSection và LeaveCriticalSection Điều đầu tiên, trong chương trình,

bạn phải định nghĩa một critical trên bộ nhớ Điều này thực hiện được bằng cách gọi

hàm InitializeCriticalSection Hàm này được khai báo như sau:

procedure InitializeCriticalSection(var lpCriticalSection: TRTLCriticalSection); stdcall;

Trang 8

InitializeCriticalSection lấy một tham số kiểu TRTLCriticalSection, mà trường của nó

lưu trữ thông tin về critical section Bạn không cần quan tâm về cấu trúc của nó, bởi bì

chẳng cần thao tác trên đó Hãy khai báo một biến toàn cục kiểu TRTLCriticalSection

Sau khi làm critical xong, hãy hủy nó bằng hàm DeleteCriticalSection Cũng giống

như InitializeCriticalSection, hàm này có một tham số kiểu TRTLCriticalSeciont

Trong trường hợp này, hai tham số biến trong DeleteCriticalSection và

InitializeCriticalSection là một Trong chương trình bạn hãy gõ vào các lệnh sau:

Trang 9

1.3.4 Sử Dụng Critical Section trong chương trình

Đặt critical section để dùng trong thread thì rất dễ Bạn chỉ cần xem một đoạn mã ví dụ dưới đây thì sẽ biết ngay:

2 Giao tiếp giữa các máy mô hình Client/Server

Trong đề tài thực tập này, ta dùng ngôn ngữ lập trình Delphi để giao tiếp giữa các máy qua mô hình Client/Server, cụ thể là sử dụng các control như : TClientSocket,

ClientWinSocket, TServerSocket, TServerWinSocket Hình dưới đây liệt kê các lớp của socket control:

Trang 10

2.1 TClientSocket

TClientSocket được dùng để kết nối đến một Server Socket Để sử dụng control này, bạn nên làm các thao tác sau đây:

(1) Viết mã cho OnRead Event

(2) Định Address property đến Server address.

(3) Định Port là giá trị Port Property của TServerSocket muốn kết nối.(4) Định ClientType property đến ctNonBlocking.

(5) Gọi Open method để kết nối đến remote Server.Ta nói thêm về ClientType property

Nếu ClientType = ctNonBlocking, khi chương trình đọc hay ghi dữ liệu đến socket, chương trình sẽ thực hiện lệnh I/O này rồi tiếp tục thực hiện chương trình ngay cả thao tác I/O này chưa thực hiện xong.

Nếu ClientType = ctBlocking, chương trình sẽ tạm không chạy tiếp mà chờ cho đến khi thao tác I/O thực hiện xong.

Trong chương trình này, ta sẽ cho ClientType = ctNonBlocking.

2.1.1 Ghi dữ liệu đến server

Khi bạn muốn gửi dữ liệu đi, dùng lệnh tương tự như sau:

Trang 11

2.1.2 Đọc dữ liệu từ server

Bạn có thể đọc dữ liệu từ Server bằng cách dùng lệnh ReceiveText hay ReceiveBuf đặt trong OnRead Event.

procedure TChatForm.ClientSocketRead(Sender: TObject;

Ta sẽ mô tả một số hàm quan trọng trong TClientWinSocket.

function ReceiveBuf(var Buf; Count: Integer): Integer;

ReceiveBuf đọc dữ liệu từ server socket, số byte đọc do người dùng định Dữ liệu đọc được sẽ chứa trong Buf, giá trị trả về là số byte đã thực sự đọc được.

function ReceiveText: string;

Dùng ReceiveText để đọc một chuỗi từ server socket.

function SendBuf(var Buf; Count: Integer): Integer;

Dùng SendBuf để truyền dữ liệu trong Buf đến server socket Hàm này trả về số byte thực sự đã truyền.

procedure SendText(const S: string);

Dùng SendText để truyền một chuỗi đến server socket.

Trang 12

function SendStream(AStream: TStream): Boolean;

Dùng SendStream để truyền tất cả thông tin trong AStream đến server socket Hàm này trả về true nếu dữ liệu đã thực sự truyền đi Bạn không cần phải giải phóng bộ nhớ cho AStream, windows socket sẽ giải phóng nó cho bạn.

function SendStreamThenDrop(AStream: TStream): Boolean;

SendStreamThenDrop làm việc giống như SendStream, nhưng khi thi hành xong lệnh này, nó sẽ tự động terminates

procedure Lock;

Gọi Lock trước khi bắt đầu đoạn mã không thread-safe Bạn đừng dùng Lock khi thực

hiện đoạn mã như đọc và ghi lên blocking connection bởi vì nếu dùng sẽ thừa Với ClientType là ctBlocking, chương trình đã tự động tạm ngưng cho đến khi các thao tác I/O thực hiện xong.

procedure UnLock;

Gọi UnLock ở cuối đoạn mã không thread-safe mà trước đó đã dùng lệnh Lock, khi ấy

các thread khác lại tiếp tục thi hành tiếp.

2.3 TserverSocket

TServerSocket điều khiển server socket connections trong TCP/IP server

TServerSocket sẽ thiết lập kết nối với một máy khác khi máy này ra yêu cầu Server socket có thể kết nối đến một số client và bạn có thể giao tiếp với các client này.

Trang 13

2.3.1 Truyền dữ liệu đến một Client

MyServer.Socket.Connections[2].SendText("this is a test"); TServerSocket

TServerWinSocket

TCustomWinSocket[array] Câu lệnh ở trên gửi dữ liệu đến client thứ 3.

2.3.2 Đọc dữ liệu từ một client

Để đọc dữ liệu từ một Client, bạn hãy đón sự kiện OnClientRead Bạn có thể ghi lệnh

trong event OnClientRead như sau:

procedure TChatForm.ServerSocketClientRead(Sender: TObject;

Trang 14

2.3.3 Bạn có thể biết chính xác Client thứ mấy đã gửi dữ liệu đến server socket

Đoạn mã sau đây sẽ cho biết client nào đã gửi dữ liệu đến server socket: procedure TChatForm.ServerSocketClientRead(Sender: TObject; for Client := 0 to Total do

if (MyServer.Socket.Connections[Client] = Socket then

Hai nhiệm vụ chính của TServerWinSocket là:

2.4.1 Lắng nghe yêu cầu kết nối của Client

TServerWinsocket luôn lắng nghe yêu cầu kết nối từ client Khi có một yêu cầu kết nối gửi tới, TServerWinSocket sẽ tạo ra một socket control mới (kiểu

TServerWinSocket) để liên lạc với client đó socket control mới này sẽ được thêm vào một danh sách được mô tả dưới đây Công việc này là hoàn toàn tự động, người lập trình không cần quan tâm.

Trang 15

2.4.2 Quản lý dãy các client socket đã kết nối với server socket

Để liên lạc với một client, bạn phải chọn một socket trong danh sách các client, sau đó bạn có thể thực hiện các thao tác đọc ghi cho client này.

Bạn có thể dùng ActiveConnections property để giao tiếp với tất cả các client.

TServerClientWinSocket giống như TClientWinSocket, cả hai đều là con của

TCustomWinSocket Sự khác nhau giữa TClientWinSocket và TServerClientWinSocket là TClientWinSocket liên lạc với Server socket còn TServerClientWinSocket liên lạc với một client nào đó.

Trang 16

3 Giới thiệu chương trình

3.1 Nội dung và ý nghĩa chương trình

Chương trình được xây dựng trên mô hình client/server cho phép nhiều client cùng truy cập đến dữ liệu nằm trên máy server Chương trình được dùng bởi 3 nhóm đối tượng là khách hàng, người cập nhật dữ liệu về nhà cửa trên máy server và người quản lý Nếu là máy server, trên máy bạn phải có tất cả các tập tin dữ liệu của chương trình thì mới được

Nếu là khách hàng hoặc người cập nhật dữ liệu, bạn chỉ cần một chương trình thực thi là đủ Có thể bạn cũng chẳng cần phải chép chương trình về máy mình làm gì mà thực thi nó bằng cách attach đến máy server để thực thi chương trình.

Bất kỳ người dùng nào muốn truy cập đến chương trình cần phải được đăng ký một username, password và quyền sử dụng.

Khi chương trình được thực thi, một khung trao đổi hiện ra như sau:

Trang 17

* Nếu là khách hàng, bạn phải nhập các tham số sau:

+ HostName : Tên Computer của máy server + User Name: Tên đăng ký.

+ Password : Mật mã đã đăng ký + Level : Chọn Khách Hàng

Khi khách hàng yêu cầu một việc chẳng hạn đăng ký thuê một căn nhà, chương trình (client) sẽ gửi một thông điệp thuê nhà đến máy server Máy server sẽ nhận được yêu cầu này và tạo ra một thread mới để giải quyết công việc đăng ký thuê nhà cho client Tất nhiên việc tranh chấp dữ liệu phải được đề cập khi thực hiện thao tác trên Sau khi thực hiện xong, chương trình server sẽ gửi trả kết quả về cho máy client.

Người khách hàng có thể thực hiện các công việc như sau:

+ Xem thông tin về một căn nhà

+ Liệt kê các căn nhà thỏa một số điều kiện do khách hàng định như: Nhà là thuê hay bán; Nhà nội hay ngoại thành; Giá tiền nhỏ nhất và lớn nhất trong khoảng nào; Diện tích nhà nhỏ nhất và lớn nhất là bao nhiêu.

+ Đăng ký thuê một căn nhà + Đăng ký mua một căn nhà.

* Nếu là người cập nhật từ điển dữ liệu nhà, bạn phải nhập các tham số sau:

+ HostName : Tên Computer của máy server + User Name: Tên đăng ký.

+ Password : Mật mã đã đăng ký.

+ Level : Chọn Người Cập Nhật Thông Tin

Khi người cập nhật dữ liệu yêu cầu một việc chẳng hạn thêm một thông tin nhà mới, chương trình (client) sẽ gửi một thông điệp thêm thông tin nhà mới đến máy server

Trang 18

cập khi thực hiện thao tác trên Sau khi thực hiện xong, nó sẽ gửi trả kết quả về cho máy client.

Người cập nhật dữ liệu có thể làm các thao tác sau:

+ Xem thông tin về một căn nhà

+ Liệt kê các căn nhà thỏa một số điều kiện do khách hàng định như: Nhà là thuê hay bán; Nhà nội hay ngoại thành; Giá tiền nhỏ nhất và lớn nhất trong khoảng nào; Diện tích nhà nhỏ nhất và lớn nhất là bao nhiêu.

+ Thêm thông tin về một căn nhà mới + Sửa đổi thông tin một căn nhà đã có rồi + Bớt thông tin về một căn nhà khỏi từ điển.

* Nếu là người quản lý (server), bạn phải nhập các tham số sau:

+ User Name: Tên đăng ký + Password : Mật mã đã đăng ký + Level : Chọn Người Quản Lý

Các tập tin dữ liệu đều nằm trên máy server Các client không thể truy cập trực tiếp đến dữ liệu được mà chỉ gửi yêu cầu đến cho server thực hiện.

Khi Server nhận được một yêu cầu nào đó từ client, nó sẽ tạo ra một thread mới để giải quyết cho vấn đề này Nếu dữ liệu bị thay đổi, chương trình sẽ phải cập nhật thông tin ngay trên màn hình của toàn bộ các máy client.

Trang 19

Người quản lý có thể làm các thao tác sau:

+ Xem thông tin về một căn nhà

+ Liệt kê các căn nhà thỏa một số điều kiện do khách hàng định như: Nhà là thuê hay bán; Nhà nội hay ngoại thành; Giá tiền nhỏ nhất và lớn nhất trong khoảng nào; Diện tích nhà nhỏ nhất và lớn nhất là bao nhiêu.

+ Thêm thông tin về một căn nhà mới + Sửa đổi thông tin một căn nhà đã có rồi + Bớt thông tin về một căn nhà khỏi từ điển.

+ Thống kê các căn nhà đã cho thuê Chương trình liệt kê danh sách các nhà đã cho thuê kèm theo mọi thông tin về các nhà đã thuê này

+ Người quản lý có thể xem nhà nào đã hết hạn cho thuê để đưa nhà này trở về danh sách nhà có thể cho thuê.

+ Thống kê các căn nhà đã bán Người quản lý có thể xem danh sách tất cả các nhà đã bán và cả mọi thông tin về nó nữa

Ý nghĩa chính trong chương trình này là nhằm giải quyết ba vấn đề chính sau đây:

(1) Dùng thread để phân chia thời gian thực hiện công việc của từng client

Ví dụ một client nào đó yêu cầu đến server một tác vụ mà đòi hỏi một thời gian lâu mới giải quyết xong Nếu không phân chia thời gian thì trong lúc thực hiện tác vụ này cho client đó, các client khác không thể ra lệnh được cho máy server, chương trình chạy không tốt.

(2) Giải quyết tranh chấp để bảo toàn dữ liệu Nếu cùng một lúc, hai hay nhiều client

Trang 20

(3) Đây là một chương trình ứng dụng thực sự vì nó có hầu hết các tính năng của một chương trình kinh doanh nhà đất trên mạng client/server.

Phần tiếp theo ta sẽ nói chi tiết về tổ chức dữ liệu của chương trình, thông tin về nhà cửa, cách giao tiếp giữa các máy, tranh chấp dữ liệu, phân chia CPU cho client…

3.2 Các vấn đề chính cần giải quyết

3.2.1 Tổ chức dữ liệu trong chương trình

Thông tin về nhà cửa gồm có:

THomeInfo = packed record

TenNha : string[30]; // Tên nhà CapNha : byte; // Cấp nhà ChieuDai : real // Chiều dài nhà ChieuRong : real; // Chiều rộng nhà TangLau : byte; // Số lầu

PhongKhach : byte; // Số phòng khách PhongNgu : byte; // Số phòng ngủ PhongTam : byte; // Số phòng tắm DiaChi, // Địa chỉ nhà Duong, // Tên đường

ThanhPho : string[30]; // Tên thành phố Quan : string[30]; // Tên quận

NhaChoThue : boolean; // Có phải nhà cho thuê GiaMoiThang : real; // Giá tiền thuê mỗi tháng NhaBan : boolean; // Có phải nhà muốn bán TriGia : real; // Giá tiền bán

NhaNgoaiThanh : boolean; // Nha ngoại ô hay nội thành CoNuocMay : Boolean; // Nhà có nước máy không

NhaCoHeThongNuocNong : Boolean; // Nhà hệ thống nước nóng NhaCoHoBoi : boolean; // Nhà có hồ bơi không

Trang 21

TinhTrangNha : Byte; // Tình trạng nhà: Rất Tốt= 0,Tốt = 1 // Trung bình = 2, Kém = 3

TrangTriNoiThat : Byte; // Sang trọng = 0, Tốt = 1 // Trung bình = 2, Kém = 3

NhaCoVuon : boolean; // Nhà có vườn không

ChieuRongVuon : real; // Chiều rộng vườn tính theo m HuongNha : Byte; // Hướng nhà (Đông = 0, Tây = 1, ChuQuyen : Byte; // Nam = 2, Bắc = 3, Đông Bắc = 4, // Đông Nam = 5, Tây Bắc = 6

// Tây Nam = 7

DienTich : real; // Diện tích nhà (m vuông) rent_roi : boolean; // Nhà đã thuê rồi

sell_roi : boolean; // Nhà đã bán rồi

NgayDauThue : TDateTime; // Ngày bắt đầu thuê nhà NgayCuoiThue : TDateTime; // Ngày kết thúc thuê nhà end;

Các tập tin dữ liệu trong chương trình gồm có:

ltdata.dic : file of THomeInfo, chứa thông tin nhà cửa ltidx.dic : file of longint, index file

ltrent.dic : file of longint, lưu index các nhà đã cho thuê ltsell.dic : file of longint, lưu index các nhà đã bán

3.2.2 Kết nối cho client

Ta kết nối cho một client bằng đoạn mã sau:

Trang 22

3.2.3 Hủy kết nối cho client

Ta hủy kết nối cho một client bằng đoạn mã sau: ClientSocket.Close;

3.2.4 Tranh chấp dữ liệu

Để tránh dữ liệu có thể bị hư hỏng khi nhiều client cùng sửa đổi dữ liệu nằm trên máy server, chương trình đã giải quyết đượïc vấn đề này bằng cách sử dụng các hàm API của windows, xin xem phần 1.3 của bài báo cáo này.

3.2.5 Dùng thread để phân chia CPU cho các thao tác của client

Để trong cùng một thời gian, nhiều client có thể truy cập đến cùng một dữ liệu nằm trên máy server, ta dùng thread Xin xem phần 1 của bài báo cáo này để biết cách dùng

Trang 23

3.3 Các chức năng cho người quản lý

Đây là khung trao đổi chính của chương trình:

Chương trình cung cấp cho bạn hầu hết các tính năng của một trình quản lý dữ liệu thông thường.

Các thao tác trên dữ liệu thực chất đều do chương trình server đảm nhận.

Trang 24

3.3.1 Tìm kiếm một nhà

Toàn bộ nhà có trong từ điển (không kể nhà đã thuê hay bán) sẽ được liệt kê trong một listbox Danh sách nhà này được sắp xếp theo alphabet theo tên gợi nhớ của nhà.

Chương trình cho bạn một ô soạn thảo để gõ tên nhà cần tìm vào, khi gõ đến đâu, chương trình tự động nhảy đến tên nhà gần giống với tên bạn gõ vào nhất.

Giải thuật lập trình cho Tìm kiếm nhà

Ô soạn thảo TEdit đón sự kiện OnChange, mỗi khi có sự thay đổi, chương trình sẽ tạo

một thread tên THomeSearchTextThread

Hàm DoThread này chủ yếu gọi hàm HomeSearch được mô tả dưới đây: function HomeSearch (TênNhà : string; var found : boolean) : longint;

Hàm này tìm kiếm trong danh sách nhà có TênNhà như tham số đưa vào không? Input :

TênNhà : Tên nhà cần tìm Output:

found = True, tìm thấy nhà Giá trị hàm trả về là vị trí index của nhà vừa tìm được found = False, không tìm thấy nhà Giá trị trả về là vị trí index có tên nhà gần giống nhất với tên nhà cần tìm.

Trang 25

3.3.2 Lấy thông tin của một nhà

Mỗi khi người dùng nhấn chuột vào một nhà trong danh sách nhà, chương trình sẽ sinh

ra một thread tên THomeGetDataThread để lấy mọi thông tin về nhà.

Hàm DoThread này chủ yếu sẽ gọi hàm HomeGet được mô tả như sau: function HomeGet(index : longint) : THomeInfo;

Đưa vào index là vị trí cần lấy thông tin nhà Hàm này trả về kết quả kiểu ThomeInfo là thông tin của toàn bộ về nhà.

Trang 26

3.3.3 Thêm thông tin một nhà mới

Hình 3.3.3

Khi bạn nhấn vào nút thêm nhà mới, một khung trao đổi như trên sẽ hiện ra để bạn nhập thông tin về nhà mới vào Khi đã điền đủ thông tin về nhà xong, nút OK sẽ sáng lên để cho phép bạn hoàn thành công việc thêm nhà mới.

Khi nút OK được nhấn, một thread tên TInsertDataThread được sinh ra

procedure TInsertDataThread.Execute;begin

Trang 27

DoThread chủ yếu gọi hàm HomeInsert và ServerUpdateVLB được mô tả như sau: function HomeInsert(home : THomeInfo; var Index : longint) : boolean;

Hàm này thêm một nhà mới vào danh sách nhà Input

HomeInfo : Thông tin nhà cần thêm Output

index = -1 nếu không thành công

index > = 0 là vị trí của nhà mới thêm trong danh sách nhà.

Đầu tiên ta đưa dữ liệu homeInfo vào cuối datafile, sau đó ta tiến hành cập nhật file index như sau:

function HomeInsert (homeInfo : THomeInfo) : integer; begin

IndexData := filesize(dataFile); Append HomeInfo vào cuối DataFile;

Tìm index cho nhà mới thêm vào

Insert giá trị IndexData vào indexfile tại vị trí index

Nếu việc thêm nhà thành công, chương trình sẽ gửi một thông điệp đến mọi client để cập nhật danh sách nhà vừa mới bị thay đổi bằng cách gọi hàm ServerUpdateVLB được mô tả như dưới đây:

Trang 28

3.3.4 Xóa thông tin một nhà

Khi bạn chọn một nhà trong danh sách nhà rồi nhấn nút xóa nhà, một khung trao đổi Confirm hiện ra tương tự như sau:

Nhấn nút OK để quyết định xóa căn nhà tại vị trí hiện hành trong danh sách nhà Khi ấy chương trình sẽ tạo ra một thread tên TDeleteThread:

DoThread chủ yếu gọi hàm HomeDelete(index) và ServerUpdateVLB function HomeDelete (index : longint) : boolean;

Delete 1 record tại vị trí index của indexfile end;

Nếu việc xóa nhà thành công, chương trình sẽ gửi một thông điệp đến mọi client để cập nhật danh sách nhà vừa mới bị thay đổi bằng cách gọi hàm ServerUpdateVLB như trên.

Trang 29

3.3.5 Cập nhật thông tin một nhà

Hình 3.3.5.

Khi nhấn nút Thay Đổi Thông Tin Nhà, một khung trao đổi tương tự để thêm nhà mới hiện ra Các ô nhập đã được điền sẵn thông tin Bạn có thể sửa đổi một vài chỗ sai sót rồi nhấn nút OK để hoàn thành việc sửa đổi thông tin.

Trang 30

Khi nhấn nút OK, một thread tên TModifyDataThread sẽ được sinh ra

DoThread chủ yếu gọi hàm HomeModify được mô tả dưới đây:

Hàm HomeModify cập nhật thông tin nhà trong biến Home tại vị trí index Hàm trả về giá trị True nếu thành công, ngược lại cho giá trị False Thực chất của hàm này là làm 2 thao tác: xóa thông tin nhà tại vị trí index rồi thêm nhà mới vào danh sách với thông tin nằm trong biến Home.

Đưa vào :

-Home : Thông tin mới về căn nhà

-Index : Vị trí trong danh sách nhà cần sửa đổi thông tin

Cho ra:

-Index : Vị trí mới trong danh sách nhà

-Result = True nếu thành công, False nếu thất bại.

Trang 31

3.3.6 Thống kê số nhà đã cho thuê

Người quản lý có thể thống kê các nhà đã cho thuê Nhấn chuột vào nút Thống Kê Nhà Cho Thuê, một khung trao đổi Thống Kê Nhà Cho Thuê hiện ra như dưới đây:

Trong khung trao đổi này chứa danh sách các nhà đã cho thuê Bạn có thể click chuột vào một nhà trong danh sách này để xem thông tin chi tiết về nó Trong phần chi tiết này cũng chứa thông tin về thời gian bắt đầu cho thuê và ngày thuê cuối cùng, dựa vào đây, người quản lý có thể đưa các nhà đã hết hạn cho thuê chở về danh sách nhà có thể cho thuê.

3.3.6.1 Đếm số nhà đã cho thuê

Bạn có thể đếm có bao nhiêu nhà đã cho thuê bằng cách nhấn nút Đếm Nhà Đã Thuê, một khung trao đổi như sau hiện ra như sau đây cho bạn thông tin có tất cả bao nhiêu nhà đã cho thuê.

Trang 32

Để đếm số nhà đã cho thuê, chương trình sinh ra một thread tên

3.3.6.2 Đưa một nhà đã hết hạn cho thuê về danh sách các nhà có thể cho thuê

Để đưa một nhà đã hết hạn cho thuê về danh sách các nhà có thể cho thuê, bạn hãy nhấn nút Hết Thuê Nhà, một khung trao đổi Confirm hiện ra như dưới đây:

Nhấn nút Nhận để quyết định việc thôi cho thuê nhà.

Trang 33

Giải thuật cho việc đưa một nhà hết hạn thuê nhà về danh sách nhà có thể cho idSetVLBNumItems, Count, fHome);

// Gửi thông điệp đến toàn bộ client yêu cầu cập nhật lại danh sách các nhà cho thuê hoặc bán

end;end;

Trang 34

Nội dung của hàm HomeUnRent:

function THomeData.HomeUnRent(delindex : longint) : boolean; (* Đưa vào

delindex : vị trí cần xóa khỏi danh sách nhà đã cho thuê Cho ra

Result = true nếu thành công Result = false nếu thất bại

// Thêm thông tin nhà này vào danh sách nhà có thể cho thuê hoặc bán

// Các lệnh sau đây để cắt 4 byte ở vị trí delindex khỏi rentfile (sau khi làm xong rentfile

sẽ giảm đi 4 bytes.

assignfile(trent, pathname + '1z2y3x4w.qgb'); rewrite(trent);

// Tạo ra một file trent tạm thời count := delindex;

Trang 35

blockread(rentfile, buf^, count); blockwrite(trent, buf^, count); blockread(rentfile, buf^, count); blockwrite(trent, buf^, count);

Trang 36

3.3.7 Thống kê số nhà đã bán

Người quản lý có thể thống kê các nhà đã bán Nhấn chuột vào nút Thống Kê Nhà Đã Bán, một khung trao đổi Thống Kê Nhà Đã Bán hiện ra như dưới đây:

Trong khung trao đổi này chứa danh sách các nhà đã bán điâ Bạn có thể click chuột vào một nhà trong danh sách này để xem thông tin chi tiết về nó.

3.3.7.1 Đếm số nhà đã bán

Bạn có thể đếm có bao nhiêu nhà đã bán bằng cách nhấn nút Đếm Nhà Đã Bán, một khung trao đổi như sau hiện ra như sau đây cho bạn thông tin có tất cả bao nhiêu nhà đã bán.

Trang 37

Để đếm số nhà đã bán, chương trình sinh ra một thread tên

3.4 Các chức năng cho người cập nhật thông tin nhà

Dưới đây là khung trao đổi chính dành cho người cập nhật dữ liệu nhà:

Trang 38

3.4.1 Tìm kiếm một nhà

Khi người cập nhật thông tin nhà gõ vào ô soạn thảo tìm kiếm, chương trình sẽ gửi một thông điệp tìm kiếm đến máy server kèm theo nội dung tên nhà họ đã đánh vào Máy server sẽ tiến hành việc tìm kiếm này (Tạo ra một thread tên

THomeSearchTextThread) và trả về cho client index của tên nhà gần giống nhất tìm

thấy trong danh sách nhà.

3.4.2 Lấy thông tin của một nhà

Khi người cập nhật từ điển nhấn chuột vào một nhà trong danh sách nhà, chương trình sẽ gửi một thông điệp lấy thông tin nhà đến máy server, kèm theo vị trí của nhà này trong danh sách nhà Máy server sẽ tiến hành việc lấy thông tin nhà (Tạo ra một thread

tên THomeGetDataThread) và gửi kết quả về cho client Khi đã lấy được dữ liệu trên

server, chương trình client sẽ hiển thị thông tin nhà mà bạn vừa click chuột lên màn hình.

3.4.3 Cập nhật thông tin một nhà

Khi người cập nhật từ điển nhấn nút Cập Nhật Thông Tin Nhà, một khung trao đổi tương tự như hình 3.3.5 hiện ra, những thông tin cũ đã được điền sẵn rồi, bạn có thể sửa một vài chỗ sai sót sau đó nhấn nút OK Ngay lúc đó chương trình sẽ gửi một thông điệp cập nhật thông tin nhà đến chương trình trên máy server, kèm theo vị trí và thông tin mới của nhà vừa mới sửa đổi này Máy server sẽ tiến hành việc cập nhật thông tin

nhà (Tạo ra một thread tên TModifyDataThread) cho client.

Trang 39

3.4.4 Thêm thông tin một nhà mới

Nhấn vào nút thêm nhà mới, một khung trao đổi như hình 3.3 sẽ hiện ra để bạn nhập thông tin về nhà mới vào Sau khi đã điền đủ thông tin về nhà xong, nút OK sẽ sáng lên để cho phép bạn hoàn thành công việc thêm nhà mới.

Khi nút OK được nhấn, chương trình sẽ gửi một thông điệp yêu cầu thêm nhà mới cho server, kèm theo thông tin cho nhà bạn vừa nhập vào Chương trình chạy trên máy

server khi nhận được thông điệp này sẽ sinh ra một thread tên TInsertDataThread để

thực hiện việc thêm nhà mới Nếu việc thêm nhà thành công, một thông điệp yêu cầu cập nhật danh sách nhà sẽ được gửi đến cho toàn bộ client.

3.4.5 Xóa thông tin một nhà

Chọn một nhà trong danh sách nhà cần xóa rồi nhấn nút xóa nhà, một khung trao đổi Confirm hiện ra như sau:

Bạn nhấn nút Nhận để quyết định xóa, khi ấy chương trình sẽ gửi một thông điệp yêu cầu xóa nhà đến chương trình server kèm theo vị trí trong danh sách nhà Chương trình

server khi nhận được thông báo này sẽ sinh ra một thread tên TDeteleThread để thực

hiện việc xóa nhà.

Nếu công việc xóa nhà thực hiện thành công, chương trình server sẽ gửi một thông điệp yêu cầu cập nhật danh sách nhà đến toàn bộ các client.

Trang 40

3.5 Các chức năng cho một khách hàng

Dưới đây là khung trao đổi chính dành cho người khách hàng:

3.5.1 Lấy thông tin về một nhà

Khi người khách hàng nhấn chuột vào một nhà trong danh sách nhà, chương trình sẽ gửi một thông điệp lấy thông tin nhà đến máy server, kèm theo vị trí của nhà này trong danh sách nhà Máy server sẽ tiến hành việc lấy thông tin nhà (Tạo ra một thread tên

THomeGetDataThread) và gửi kết quả về cho client.

3.5.2 Tìm kiếm một nhà

Ngày đăng: 25/08/2012, 11:26

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan