50B Sử dụng MFC:

Một phần của tài liệu Lập trình mạng trên máy pocket PC (Trang 62 - 70)

Chương 3 2B Lập trình mạng trên môi trường Pocket PC 3.1 14BU Cài đặt các phần mềm cần thiết:

3.3.2 50B Sử dụng MFC:

3.3.2.1 78BGiới thiệu về lớp CSocket:

Hình 3.44 ơ đồ kế thừa của lớp CSocket.

Lớp CSocket kết thừa từ lớp cha của nó là CAsyncSocket do đó nó thừa hưởng những thành phần Windows sockets API của lớp CasyncSocket.Xem chi tiết trong MSDN.

Những phần tiếp theo chúng ta sẽ khảo sát những thành phần cơ bản của lớp CSocket hỗ trợ cho việc lập trình mạng.

3.3.2.2 79BClient:

Để có thể sử dụng được thư viện CSocket cần phải làm hai công việc một là

thêm dòng #include <afxsock.h> vào đầu tập tin có sử dụng lớp Csocket.

hàm AfxSocketInit(NULL)trước khi sử dụng các hàm của lớp Csocket mục đích là để khởi tạo thư viện. Nếu không mọi hàm sử dụng thư viện tuy được biên dịch thành công nhưng vẫn báo lỗi khi thi hành chương trình.

Để kết nối đến một cổng chở kết nối trước tiên ta phải khởi tạo một socket với hàm như sau:

BOOL Create(): Hàm tạo socket ở phia Client không có tham số. Nếu việc tạo socket thành công thì hàm sẽ trả về kết quả khác 0; nếu xảy ra lỗi thì hàm sẽ trả về kết quả là 0. Ta có thể dùng hàm int GetLastError() để lấy thông tin mã lỗi.

Sau khi đã tạo một socket thành công bước tiếp theo là ta sẽ dùng socket đó để kết nối đến Server đang mở dịch vụ ta sẽ dùng hàm sau để kết nối:

BOOL Connect( LPCTSTR Error! Hyperlink reference not valid. UINT

Error! Hyperlink reference not valid.)

lpszHostAddress: là địa chỉ của Server mà ta cần kết nối đến. Ta có thể truyền cho tham số này theo tên miền hoặc theo địa chỉ IP. Ví dụ: “2TUftp.microsoft.comU2T” hoặc “128.56.22.8” đều được. Mỗi máy tính đều có một địa chỉ IP mặc định là “127.0.0.1” hoặc “localhost”. Do đó nếu như chúng ta thực hành kết nối cho cả Server và Client trên cùng một máy thì ta có thể kết nối đến địa chỉ này.

nHostPort: Là số cổng của dịch vụ mà server đang mở. Ví dụ cổng của dịch vụ web là 80 cổng của dịch vụ ftp là 21...

Sau đây là ví dụ cho việc tạo và kết nối đến dịch vụ cổng 1111 trên Server. CSocket skConnect;

If(!skConnect.Create() || !skConnect.Connect(“localhost”1111)) {

cout<<”ket noi khong thanh cong”<<endl; exit(0);

}

Sau khi đã kết nối được server ta sẽ dùng hai hàm sau đây để gửi và nhận thông điệp.

Hàm gửi thông điệp:

int Send(const void* Error! Hyperlink reference not valid.int Error! Hyperlink reference not valid.int Error! Hyperlink reference not valid. = 0);

lpBuf: là bộ đệm dùng để chứa dữ liệu được gửi.

nBuffeLen: Chiều dài của dữ liệu lpBuf dưới dạng Byte.

nFlags: Mặc định là 0 ta có thể không cần truyền tham số này.

Nếu không có lỗi xảy ra thì hàm này sẽ trả về giá trị tổng số kí tự được gửi(giá trị này phải nhỏ hơn giá trị của nBufLen). Nếu xảy ra lỗi thì hàm sẽ trả về giả trị SOCKET_ERROR. Chúng ta có thể tìm được mã lỗi thông qua hàm int

GetLastError(). Xem thêm trong MSDN.

Hàm nhận thông điệp từ socket:

virtual int Receive( void*Error! Hyperlink reference not valid.int Error! Hyperlink reference not valid.int Error! Hyperlink reference not valid. = 0);

Tất cả những tham số này đều có ý nghĩa tương tự như các tham số của hàm Send() ở trên.Nếu không có lỗi xảy ra thì giá trị trả về của hàm này là tổng số byte nhận được. Nếu đã đóng kết nối socket thì kết quả trả về là 0. Nếu xảy ra lỗi thì kết quả trả về sẽ là một SOCKET_ERROR được xác định trong hàm int GetLastError(). Tham khảo mã lỗi trong MSDN.

Ví dụ sau sẽ trình bày minh họa cho việc gửi và nhận dữ liệu: Char msg[1000];

Int msg_len; While(1) {

cout<<”Nhap thong diep: “;

msg_len = strlen(msg); //Gửi thông điệp đến server

skConnect.Send(&msg_len sizeof(msg_len)); //Gửi chiều dài thông điệp. skConnect.Send(msgmsg_len);//Gửi nội dung thông điệp.

//Nhận thông điệp đến server

skConnect.Receive(&msg_len sizeof(msg_len)); //nhận chiều dài thông điệp. skConnect.Receive(msgmsg_len);//Nhận nội dung thông điệp.

}

Cuối cùng sau khi hoàn tất truyền dữ liệu đóng kết nối với câu lệnh như sau: virtual void Close();

Sau đây là toàn bộ nội dung đã thực hiện cho client.

CSocket skConnect;

If(!skConnect.Create() || !skConnect.Connect(“localhost”1111)) {

cout<<”ket noi khong thanh cong”<<endl; exit(0);

}

else cout<<”kết nối thành công”; Char msg[1000];

Int msg_len; While(1) {

cout<<”Nhap thong diep: “;

gets(msg);

//Gửi thông điệp đến server

skConnect.Send(&msg_len sizeof(msg_len)); //Gửi chiều dài thông điệp. skConnect.Send(msgmsg_len);//Gửi nội dung thông điệp.

//Nhận thông điệp đến server

skConnect.Receive(&msg_len sizeof(msg_len)); //nhận chiều dài thông điệp. skConnect.Receive(msgmsg_len);//Nhận nội dung thông điệp.

skConnect[msg_len] = 0;//Kết thúc chuỗi. }

skConnect.Close();

3.3.2.3 80BServer:

Cũng tương tự như các phía Client điều trước tiên chúng ta cần làm là khởi tạo một socket dùng để tạo dịch vụ. Câu lệnh khởi tạo socket phía server có hơi khác so với phía Client. Nguyên mẫu của hàm như sau:

BOOL Create(UINT Error! Hyperlink reference not valid. = 0int Error! Hyperlink

reference not valid. = SOCK_STREAMLPCTSTR Error! Hyperlink reference not

valid. = NULL);

nSocketPort: Số cổng mà ta sử dụng để mở dịch vụ.

nSocketType: SOCK_STREAM(tương ứng với giao thức TCP) hoặc là SOCK_DGRAM(tương ứng với giao thức UDP). Mặc định của hàm là SOCK_STREAM.

Error! Hyperlink reference not valid. :là chuỗi con trỏ chứa địa chỉ mạng của

một kết nối socket. Mặc định là NULL.

Giá trị khác 0 sẽ được hàm này trả về nếu không có lỗi xảy ra. Ngược lại là 0.Chúng ta có thể tham khảo mã lỗi thông qua hàm int GetLastError();

Trong CSocket chúng không cần thiết phải gọi hàm bind() bởi vì sau khi gọi hàm Create() thì tự động hàm bind() sẽ được gọi để kết buộc socket đến địa chỉ xác

định.

Sau khi đã khởi tạo socket thành công tiếp theo ta sử dụng hàm Listen để nghe ngóng kết nối.

BOOL Listen(int Error! Hyperlink reference not valid. = 5);

Error! Hyperlink reference not valid.: Chiều dài tối đa có mà hàng đợi của những kết nối vào có thể chứa được. Giá trị này giới hạn trong khoảng từ 1 đến 5; mặc định là 5.

Nếu không có lỗi thì hàm này sẽ trả về giá trị khác không; ngược lại sẽ cho giá trị là không và mã lỗi sẽ được xác định thông qua hàm GetLastError.

Để chấp nhận một kết nối vào trước tiên cần phải khởi tạo socket bằng hàm Create sau đó một backlog (dãy) các kết nối vào sẽ được xác định bởi hàm Listen. Sau đó những kết nối này sẽ được chấp nhận bởi hàm Accept. Hàm Listen chỉ áp dụng cho những socket hỗ trợ kết nối điển hình là dạng SOCK_STREAM. Socket này được đặt ở chế độ “bị động”_ chế độ mà những kết nối vào được thừa nhận và được xếp hàng chờ đợi bởi tiến trình này.

Hàm này thường được sử dụng ở Server(hoặc có thể ở bất kỳ ứng dụng nào

muốn chấp nhận kết nối vào) cho phép có nhiều hơn một kết nối được yêu cầu ở cùng một thời điểm. Nếu có yêu cầu kết nối nhưng hàng đợi đã đầy(nConnectionBacklog = 5) thì client sẽ nhận một lỗi WSAECONNREFUSED.

Tiếp theo ta sử dụng hàm Accept để chấp nhận kết nối.

virtual BOOL Accept(

CAsyncSocket& Error! Hyperlink reference not valid.

SOCKADDR* Error! Hyperlink reference not valid. = NULL int* Error! Hyperlink reference not valid. = NULL

);

rConnectedSocket: Tham chiếu đến socket mới được lấy tự Client.

lpSockAddr hoặc lpSocketAddrLen có giá trị là NULL thì sẽ không có thông tin nào về địa chỉ của socket vừa được kết nối được trả về. Mặc định là NULL.

Error! Hyperlink reference not valid. : Là con trỏ trỏ đến chiều dài chương trình của

của địa chỉ trong lpSockAddr dưới dạng byte.

Tương tự như các phương thức ở trên giá trị trả về của hàm này là khác 0 nếu hàm chương trình thực hiện thành công ngược lại sẽ bằng 0. Mã lỗi sẽ được xác định

thông qua hàm GetLastError.(xem chi tiết trong MSDN).

Sau khi đã chấp nhận kết nối ta có thể dùng các hàm Send Receive để truyền và nhận thông điệp và hàm Close để đóng socket giống như đã làm ở Client.

Ví dụ sau sẽ trình bày cách thức một server chấp nhận một kết nối vào:

Các biến được sử dụng trong ví dụ này sẽ gồm 2 biến CSocket một để mở cổng và một để truyền dữ liệu (Trong thực tế một cổng có thể cho phép nhiều client nối vào khi đó vẫn chỉ có một CSocket để mở cổng nhưng sẽ có nhiều CSocket để truyền dữ liệu). CSocket skListen skConnect;

If(!skListen.Create(1111) || !skListen.Listen() || !skListen.Accept(skConnect)) {

cout<<”server socket bi loi”; exit(0);

} else {

//truyền thông điệp qua lại giữa client và server. char msg[1000];

int msg_len; while(1); {

skConnect.Receive(&msg_len sizeof(msg_len)); //nhận chiều dài thông điệp.

skConnect.Receive(msgmsg_len);//Nhận nội dung thông điệp.

skConnect[msg_len] = 0; //Kết thúc chuỗi.

//Gửi thông điệp đến Client

skConnect.Send(&msg_len sizeof(msg_len)); //Gửi chiều dài thông điệp.

skConnect.Send(msgmsg_len);//Gửi nội dung thông điệp. }

skConnect.Close(); }

Một phần của tài liệu Lập trình mạng trên máy pocket PC (Trang 62 - 70)

Tải bản đầy đủ (PDF)

(90 trang)