Socket được hiểu như một ổ cắm nối giữa máy chủ và máy con. Mỗi một ổ cắm sẽ quy định một cổng (port) để mở kết nối. Người lập trình khi sử dụng socket để kết nối phải tránh những cổng được quy định thành chuẩn cho các mạng riêng biệt sau đây:
Dịch vụ Số cổng Ftp 21 Http 80 Telnet 23 Finger 79 Sntp 25
Mô hình lập trình mạng thông qua Socket sẽ thông qua hai đối tượng sau:
Đối tượng TServerSocket: Dùng phục vụ cho máy chủ. Sau đây là các thuộc tính và sự kiện quan trọng:
Thuộc tính Ý nghĩa
Active Đặt server socket vào trạng thái hoạt động hoặc tạm dừng Port Số cổng mà server socket phục vụ
Service Tên của ứng dụng hay dịch (không bắt buộc)
Sự kiện Ý nghĩa
OnAccept Chấp nhận kết nối từ máy con hay không OnClientConnect Tiếp nhận kết nối từ client
OnClientDisconnect Ngắt kết nối với client
OnClientRead Đọc dữ liệu do máy client gởi đến
Đối tượng TClientSocket dùng để phục vụ cho máy con. Sau đây sẽ liệt kê các thuộc tính và sự kiện của TClientSocket.
Thuộc tính Phương thức
Address Địa chỉ máy chủ
Port Cổng phục vụ của máy chủ Service Tưởng tự máy chủ
Host Địa chỉ IP Các sự kiện thông dụng
Sự kiện Ý nghĩa
OnConnect Kết nối thành công với máy chủ OnDisconnect Ngắt kết nối với máy chủ
OnError Quá trình kết nối hay chuyển dữ liệu bị lỗi OnRead Đọc dữ liệu trả về từ máy chủ
Chúng ta nghiên cứu thông qua chương trình chat sau:
Hình 115-Chương trình chat đơn giản Mã lệnh được liệt kê kèm theo chú thích như sau:
void __fastcall TChatForm::FileListenItemClick(TObject *Sender) { FileListenItem->Checked = !FileListenItem->Checked; if (FileListenItem->Checked) { ClientSocket->Active = false; ServerSocket->Active = true; StatusBar1->Panels->Items[0]->Text = "Listening..."; }else { if (ServerSocket->Active) { ServerSocket->Active = false; } StatusBar1->Panels->Items[0]->Text = ""; } } //--- //--- void __fastcall TChatForm::FileConnectItemClick(TObject *Sender) {
if (ClientSocket->Active) {
ClientSocket->Active = false; }
if (InputQuery("Computer to connect to", "Address Name:", Server)) { if (Server.Length() > 0) { ClientSocket->Host = Server; ClientSocket->Active = true; FileListenItem->Checked = false; } } } //--- //--- void __fastcall TChatForm::Exit1Click(TObject *Sender) { ServerSocket->Close(); ClientSocket->Close(); Close(); } //--- //---
void __fastcall TChatForm::Memo1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if (Key == VK_RETURN) { if (IsServer){ServerSocket->Socket->Connections[0]->SendText( Memo1->Lines->Strings[Memo1->Lines->Count - 1]); } else { ClientSocket->Socket->SendText(Memo1->Lines->Strings[ Memo1->Lines->Count -1]);} } } //--- //--- void __fastcall TChatForm::FormCreate(TObject *Sender) {
FileListenItemClick(NULL); }
//--- //--- void __fastcall TChatForm::ClientSocketConnect(TObject *Sender, TCustomWinSocket *Socket)
{
StatusBar1->Panels->Items[0]->Text = "Connect to: " + Socket->RemoteHost; }
//--- //--- void __fastcall TChatForm::Disconnect1Click(TObject *Sender) {
ClientSocket->Active = false; ServerSocket->Active = true;
StatusBar1->Panels->Items[0]->Text = "Listening..."; }
//--- //--- void __fastcall TChatForm::ClientSocketRead(TObject *Sender, TCustomWinSocket *Socket) { Memo2->Lines->Add(Socket->ReceiveText()); } //--- //---
void __fastcall TChatForm::ServerSocketClientRead(TObject *Sender, TCustomWinSocket *Socket) { Memo2->Lines->Add(Socket->ReceiveText()); } //--- //--- void __fastcall TChatForm::ServerSocketAccept(TObject *Sender, TCustomWinSocket *Socket)
{
IsServer = true;
StatusBar1->Panels->Items[0]->Text = "Connect to: " + Socket->RemoteAddress; }
//--- //---
void __fastcall TChatForm::ServerSocketClientConnect(TObject *Sender, TCustomWinSocket *Socket) { Memo2->Lines->Clear(); } //--- //---
void __fastcall TChatForm::ClientSocketDisconnect(TObject *Sender, TCustomWinSocket *Socket) { FileListenItemClick(NULL); } //--- //--- void __fastcall TChatForm::ClientSocketError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode) {
Memo2->Lines->Add("Error connecting to:" + Server); ErrorCode = 0;
}
//--- //---
void __fastcall TChatForm::ServerSocketClientDisconnect(TObject *Sender, TCustomWinSocket *Socket)
{
StatusBar1->Panels->Items[0]->Text = "Listening..."; }
BÀI 8- XÂY DỰNG VÀ TRIỂN KHAI CÁC ỨNG DỤNG 1. Các kỹ thuật gỡ rối trong C++ Builder
Khi lập trình với C++ Builder, chương trình được biên dịch thành tập tin .exe mặc định đã kèm chương trình gỡ rối được biên dịch bên trong. Chương trình này có nhiệm vụ kiểm soát các lỗi phát sinh trong quá trình thực thi chương trình cả lỗi do lập trình và lỗi do hệ điều hành phát sinh.
Các chức năng này được kích hoạt và điều chỉnh trong hộp thoại Tools/Debugger Options...
Hình 116-Hộp thoại tinh chỉnh Debugger Options
Thông thường thì các chức năng được cài đặt mặc định của C++ Builder phù hợp với đa số chương trình mà chúng ta tạo ra.
Tuy nhiên, chúng tôi đề nghị để truy bắt lỗi ngoại lệ có thể phát sinh do quá trình lập trình chủ quan. Chúng ta nên dùng chức năng truy bắt ngoại lệ của C++ Builder. C++ Builder cung cấp một khối lệnh try để truy bắt lỗi chặc chẽ trong cả hai trường hợp lỗi do chương trình và lỗi do phát sinh.
Chúng ta có thể nghiên cứu thêm về lĩnh vực này trong tài liệu hướng dẫn của C++ Builder.
2. Sử dụng tài nguyên Windows để xây dựng trợ giúp trực tuyến.
Sau khi cài đặt xong C++ Builder, chúng ta sẽ nhận được công cụ miễn phí Html Help Workshop. Công cụ này cho phép chúng ta tạo các tập tin trợ giúp dạng .hlp.
Chúng ta có thể khởi động bằng cách chọn Start/Program Files/HTML Help Workshop/HTML Help Workshop. Khi khởi động xong chúng ta nhận giao diện như sau:
Hình 117-Cửa sổ chương trình HTML Help Workshop
Trước tiên chúng ta cần tạo nội dung cho file Help. Để tạo nội dung các file này chúng ta mở FontPage express, hoặc FrontPage 98, 2000 và đánh vào nội dung mà chúng ta cần chỉ ra để hướng dẫn người sử dụng. Sau đó chúng ta lưu các file này lên đĩa với các tên như sau: Congty.htm, Diachi.htm, hdCaidat.htm, hdSudung.htm, Sanpham.htm, Ykien.htm, Index.htm (dùng trong ví dụ này).
Một ví dụ về cách tạo các file này dùng FrontPage 2000 (tương tự cho Frontpage 98 và FrontPage express):
Nhấn Start/Programs/Microsoft Frontpage màn hình chính xuất hiện, chúng ta gõ nội dung vào cửa sổ soạn thảo.
Chúng ta chọn Tab Normal ở dưới cùng (ngầm định chọn) và đánh nội dung vào màn hình bỏ