1. Trang chủ
  2. » Công Nghệ Thông Tin

BÀI GIẢNG MÔN LẬP TRÌNH MẠNG

40 415 0

Đ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

Thông tin cơ bản

Định dạng
Số trang 40
Dung lượng 1,21 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

• addr: địa chỉ cấu trúc dùng để chứa thông tin socket phía kết nối đến.. • addr: địa chỉ cấu trúc dùng để chứa thông tin socket phía kết nối đến.. _ Trường hợp lấy thông tin phía kết nố

Trang 1

_ Xác định bởi những bit nhận dạng (Class ID):

– Sự tương quan giữa lớp và kích thước mạng:

a) Lớp Internet (Internet Layer)

_ Giao thức Internet (IP – Internet Protocol)

_ Giao thức Kiềm soát Thông điệp Internet (Internet Control Message Protocol – ICMP)

_ Giao thức Nhóm Thông điệp Internet (Internet Group Message Protocol – IGMP)

_ Giao thức Phân giải Địa chỉ (Address Resolution Protocol – ARP), giao thức Chuyển đổi Địa chỉ (Address Reverse Protocol – ARP): chuyển đổi địa chỉ vật lý, luận lý

Trang 2

b) Lớp Giao vận (Transport Layer)

_ Cung cấp dịch vụ truyền thông giữa các tiến trình

_ Thông tin xác định tiến trình:

_ Giao thức Kiểm soát Truyền thông (Transmission Control Protocol – TCP):

• Có thiết lập cầu nối: full duplex

• Tin cậy: đúng trình tự, không thất thoát, không trùng lấp

• Byte stream: đệm dữ liệu (nơi lưu trữ dữ liệu trước khi gửi; ví dụ: nếu đệm là 1 KB, gói dữ liệu

là 2 KB thì chỉ có 1KB được chuyển phải gửi lại thêm 1 KB nữa)

_ Giao thức Dữ liệu Người dùng (User Datagram Protocol – UDP):

• Không thiết lập cầu nối

• Không tin cậy

• Dạng truyền thông (broadcast)

• Dữ liệu Người dùng (datagram)

c) Lớp Ứng dụng (Application Layer)

_ Cung cấp việc vận chuyển dữ liệu trong suốt giữa các hệ thống đầu cuối (end systems)

II Ứng dụng mạng

_ Truyền tải tập tin (File Transfer)

_ Trình duyệt web / server (Web Browser / Server)

_ Thư điện tử (Electric Mail)

_ Truyền tải giọng nói (Voice over IP)

_ Xem phim, nghe nhạc trực tuyến (Audio / Video Online)

_ Hội họp từ xa (Remote Conferencing)

_ Trò chơi trực tuyến (Game Online)

_ …

III Mô hình ứng dụng

_ Mô hình 2 tầng (2-tiers): Client / Server

_ Mô hình đa tầng (N-tiers)

_ Mô hình hàng ngang (Peer to Peer)

IV Giao diện lập trình socket

1 Window Socket API

_ Khái quát:

• Phát triển theo đặc tả giao diện Phân phối Phần mềm Berkeley (Berkeley Soft ware Distribution – BSD Socket)

• Bổ sung các tính năng hoạt động của môi trường Windows

• Hiện thực ở dạng thư viện liên kết động: wsock32.dll (winsock.h), ws2_32.del (winsock.h)

• Thư viện lập trình giao tiếp với giao thức mạng

_ Dữ liệu: socket, địa chỉ IP, thông tin máy

_ Các hàm: liên kết thư viện truy xuất thông tin, chuyển đổi dữ liệu, làm việc với socket

2 Tiếp cận hướng đối tượng

a) MFC

_ Thư viện hỗ trợ của Microsoft:

• Che giấu chi tiết sử dụng các hàm Winsock API

• Hỗ trợ xây dựng ứng dụng Internet

_ Windows Sockets: CasyncSocket, Csocket, CsocketFile

_ Mở rộng: Win32 Internet Extensions Winlnet:

• ElnternetSession

• ElnternetConnection: CftpConnection, CgopherConection, ChttConnection

• CgopherLocation

Trang 4

Chương 2: CĂN BẢN LẬP TRÌNH WINSOCK

I Socket

1 Khái niệm

_ Cơ chế trừu tượng dùng cho quá trình truyền thông giữa các tiến trình

_ Tương ứng với cấu trúc chứa các thông tin cần cho quá trình truyền thông giữa các tiến trình (IP, port)

2 Quản lý socket

_ Cấu trúc dữ liệu do hệ điều hành quản lý

_ Ứng dụng sử dụng thông qua handle

3 Phân loại

_ Stream Socket: TCP Socket

_ Datagram Socket: UDP Socket

_ Raw Socket

II Phân nhóm hàm thư viện

_ Liên kết thư viện, kết thúc

_ Truy xuất thông tin

_ Chuyển đổi dạng dữ liệu

_ Các hàm thao tác trên socket:

• Tạo socket, đóng socket

• Thiết lập cầu nối

• Gửi, nhận dữ liệu

III Liên kết thư viện

_ Liên kết thư viện: int WSAStartup (WORD wVersionRequested, LPWSADATA lpwaData); _ Kết thúc: int WSACleanup();

_ Truy xuất mã lỗi sai: int WSAGetLastError();

IV Truy xuất thông tin

1 Thông tin máy

_ Các phương thức:

• int gethost name (char FAR* name, int len);

• PHOSTENT gethostbyname (const char FAR* hostname);

• PHOSTENT gethostbyaddr (const char FAR* addr, int len, int af);

_ Ví dụ:

char sethostName [MAX_LEN];

if (gethostname (sethostName, MAX_LEN) != SOCKET_ERROR)

{ //… } else { //… }

_ Cấu trúc thông tin máy:

• struct hostent

{

Trang 5

char FAR* h_name;

char FAR* FAR* h_aliases;

short h_addtype;

short h_lenght;

char FAR* FAR* h_addr_list;

#define h_addr h_addr_list[0];

PSERVENT getservbyname (constchar char FAR* name, const FAR* proto);

V Chuyển đổi thông tin dữ liệu

1 Chuyển đổi trật tự byte

_ Trật tự byte:

• Lưu trữ số nguyên trên máy tính:

Host Byte Order Little-Endian Big-Endian

• Quy ước lưu trữ số nguyên trên mạng (Network Byte Order): Big-Endian

_ Các hàm chuyển đổi:

• u_short ntohs (u_short);

• u_long ntohl (u_long);

• u_short htons (u_short);

• u_long htonl (u_long);

2 Chuyển đổi dạng địa chỉ

_ Dạng biểu diễn địa chỉ IPv4:

• Số nguyên 4 byte

• Chuỗi dấu chấm thập phân (Dotted Decimal)

_ Các hàm chuyển đổi:

• unsigned long inet_addr (const char FAR* CD);

• char FAR* inet_ntoa (struct in_addr in);

_ Cấu trúc địa chỉ:

struct in_addr

{

union {

struct { u_char s_b1, s_b2, s_b3, s_b4; } S_un_b;

struct { u_short s_w1,s_w2; } S_un_w;

u_long S_addr;

} S_un;

#define s_addr S_un.S_addr // can be used for most tcp & ip code

#define s_host S_un.S_un_b.s_b2 // host on imp

#define s_net S_un.S_un_b.s_b1 // network

#define s_imp S_un.S_un_w.s_w2 // imp

#define s_impno S_un.S_un_b.s_b4 // imp #

#define s_lh S_un.S_un_b.s_b3 // logical host

Trang 6

}

memcpy (&inAddr, pHost->h_addr, 4);

VI Các hàm socket

1 Quy trình sử dụng

a) Có thiết lập cầu nối

b) Không thiết lập cầu nối

Trang 7

2 Chi tiết sử dụng

a) Tạo socket

_ Cú pháp: SOCKET socket (int af, int type, int protocol);

_ Thông số:

• af: họ địa chỉ AF_INET

• type: loại địa chỉ – SOCK_STREAM (có thiết lập cầu nối – TCP), SOCK_DGRAM (không thiết lập cầu nối – UDP)

• protocol: loại giao thức – 0

_ Kết quả trả về:

• Thành công: handle của socket vừa tạo

• Thất bại: INVALID_SOCKET

_ Ví dụ:

SOCKET s; // socket descriptor

char lpszMessage[100]; // informational message

s = socket(AF_INET, SOCK_STREAM, 0);

if (s == INVALID_SOCKET)

wsprintf (lpszMessage, “socket() generated error %d”, WSAGetLastError());

else lstrcpy(lpszMessage, “socket() succeeded”);

MessageBox(NULL, lpszMessage, “Info”, MB_OK);

b) Đóng socket

_ Cú pháp: int closesocket(SOCKET s);

_ Thông số: s: handle máy muốn đóng

_ Kết quả trả về: Thất bại: SOCKET_ERROR

c) Gán thông tin socket

_ Cú pháp: int bind (SOCKET s, const struct sockaddr FAR* addr, int addrlen); _ Thông số:

• s: handle của socket chờ gán thông tin

• addr: địa chỉ cấu trúc dùng để chứa thông tin socket phía kết nối đến

• addrlen: địa chỉ biến chứa kích thước cấu trúc bởi addr

_ Cấu trúc thông tin socket:

struct sockaddr

{

u_short sa_family; // address family char sa_data[14]; // up to 14 bytes of direct address };

struct sockaddr_in

{

short sin_family; // address family u_short sin_port; // service port struct in_addr sin_addr; // Internet address char sin_zero[8]; // filler

Trang 8

};

_ Ví dụ:

SOCKET s; // socket descriptor

char lpszMessage[100]; // informational message

SOCKADDR_IN addr; // Internet address

// create a stream socket

// bind the socket to its address

if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) {

wsprintf(lpszMessage, “ bind() generated error %d”, WSAGetLastError());

MessageBox(NULL, lpszMessage, “Info”, MB_OK);

} else { // } }

• Trường hợp không chỉ định port: sin_port = 0;

• Lấy thông tin socket: int getsockname (SOCKET s, struct sockAddr* addr, int* addrlen);

d) Lắng nghe

_ Cú pháp: int listen (SOCKET s, int backlog);

_ Thông số:

• s: handle máy muốn đóng

• backlog: kích thước hàng đợi kết nối

_ Kết quả trả về: Thất bại: SOCKET_ERROR

_ Ví dụ:

SOCKET s; // socket descriptor

char lpszMessage[100]; // informational message

SOCKADDR_IN addr; // Internet address

// create a stream socket

// bind the socket to its address

if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) != SOCKET_ERROR) {

// listen for connections (queueing up to three)

if (listen(s, 3) == SOCKET_ERROR) {

wsprintf(lpszMessage, “listen() generated error %d”, WSAGetLastError());

MessageBox(lpszMessage, “Info”);

} else { // } }

}

e) Tiếp nhận

_ Cú pháp: SOCKET socket (SOCKET s, struct sockAddr FAR* addr, int FAR* addrlen);

Trang 9

_ Thông số:

• s: handle của socket chờ tiếp nhận “nói” (“lắng nghe”)

• addr: địa chỉ cấu trúc dùng để chứa thông tin socket phía kết nối đến

• addrlen: địa chỉ biến chứa kích thước cấu trúc bởi addr

_ Kết quả trả về:

• Thành công: handle của socket giao tiếp với phía kết nối đến

• Thất bại: INVALID_SOCKET

_ Ví dụ:

SOCKET s; // socket descriptor

SOCKET clientS; // client socket descriptor

char lpszMessage[100]; // informational message

SOCKADDR_IN addr; // Internet address

SOCKADDR_IN clientAddr; // Internet address

IN_ADDR clientIn; // IP address

// bind the socket to its address

if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) != SOCKET_ERROR) {

// listen for connections (queueing up to three)

if (listen(s, 3) != SOCKET_ERROR) {

// set the size of the client address structure nClientAddrLen = sizeof(clientAddr);

// accept a connection clientS = accept(s, (LPSOCKADDR)&clientAddr,

&nClientAddrLen);

if (clientS == INVALID_SOCKET) {

wsprintf(lpszMessage, “ accept() generated error

%d”, WSAGetLastError());

MessageBox(lpszMessage, “Info”);

} else {

// copy the four byte IP address into an IP address structure

memcpy(&clientIn, &clientAddr.sin_addr.s_addr, 4); // print an informational message

wsprintf(lpszMessage,

“accept() ok: client IP address is %s, port is

%d”, inet_ntoa(clientIn), ntohs(clientAddr.sin_port));

MessageBox(lpszMessage, “Info”);

} }

} }

Trang 10

_ Trường hợp lấy thông tin phía kết nối sau khi tiếp nhận kết nối: int getpeername (SOCKET s, struct sockAddr* addr, int* addrlen);

wsprintf(lpszMessage, “getpeername() generated error %d”, WSAGetLastError());

MessageBox(lpszMessage, “Info”);

} else {

// copy the four byte IP address into an IP address structure

• s: handle của socket thực hiện kết nối

• addr: địa chỉ cấu trúc dùng để chứa thông tin socket phía chờ kết nối

• addrlen: địa chỉ biến chứa kích thước cấu trúc bởi addr

_ Kết quả trả về: Thất bại: SOCKET_ERROR

_ Ví dụ:

bool ConnectToServer (const Cstring &sServerAddress, short nServerPort) {

bool bSuccess = true;

m_hSocket = socket (AP_INET, SOCK_STREAM, 0);

if (m_hSocket == INVALID_SOCKET) bSuccess = false;

else {

bSuccess = false;

closesock(m_hSocket);

Trang 11

} return bSuccess;

} }

g) Gửi nhận

_ Có thiết lập cầu nối:

• Cú pháp:

int send (SOCKET s, const char FAR* buf, int len, int flags);

int recv (SOCKET s, const char FAR* buf, int len, int flags);

• Thông số:

 s: handle của socket bên gửi

 buf: địa chỉ vùng đệm chứa dữ liệu cần gửi

 len: kích thước dữ liệu gửi (tính theo byte)

 flags: 0, MSG_DONTROUTR, MSG, OOB

int nError; // error status // create, bind, and connect socket s

lstrcpy(pszBuf, “Hello, World!”);

nBufLen = lstrlen(pszBuf);

nBytesSent = send(s, pszBuf, nBufLen, 0);

if (nBytesSent == SOCKET_ERROR) r = WSAGetLastError();

else { // }

 Nhận:

SOCKET s; // socket to communicate over

#define BUFSIZE (100) // receive buffer size char pszBuf[BUFSIZE]; // buffer to receive data int nBytesRecv; // number of bytes received int nError; // error status

// create, bind, and connect socket s

nBytesRecv = recv(s, pszBuf, BUFSIZE, 0);

if (nBytesRecv == SOCKET_ERROR) nError = WSAGetLastError(); else { // }

_ Không thiết lập cầu nối:

 s: handle của socket bên gửi

 buf: địa chỉ vùng đệm chứa dữ liệu cần gửi

 len: kích thước dữ liệu gửi (tính theo byte)

 flags: 0, MSG_DONTROUTR, MSG, OOB

Trang 12

if (nBytesSent == SOCKET_ERROR) { // } else { // }

closesocket(s);

}

 Nhận:

char pszMessage[100]; // informational message

SOCKET s; // socket to receive data on

SOCKADDR_IN addr; // address of the socket

#define BUFSIZE (100) // receive buffer size

char pszBuf[BUFSIZE]; // receive buffer

int nBytesRecv; // number of bytes received

int nError; // error code

SOCKADDR_IN addrFrom; // address of sender

int nAddrFromLen = sizeof(addrFrom); // lengh of sender structure

IN_ADDR inFrom; // IP address of sender

// bind the name to the socket

if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)

{

nError = WSAGetLastError();

//

} else

Trang 13

{

nBytesRecv = recvfrom(s, pszBuf, 100, 0, (LPSOCKADDR)&addrFrom, &nAddrFromLen);

if (nBytesRecv == SOCKET_ERROR) {

nError = WSAGetLastError();

//

} else {

// got some data

// copy the four byte IP address into an IP address structure

memcpy(&inFrom, &addrFrom.sin_addr.s_addr, 4);

// print an informational message wsprintf(pszMessage,

“server received %d bytes from %s, port is

%d”,

nBytesRecv, inet_ntoa(inFrom), ntohs(addrFrom.sin_port));

} closesocket(s);

} }

3 Hai chế độ hoạt động của socket

a) Blocking

_ Các hàm thực hiện hoạt động nhập / xuất trên socket chỉ trả về khi tác vụ hoàn tất → Tiến trình bị chặn nếu tác vụ chưa hoàn tất (sự kiện mong đợi chưa xảy ra)

b) Non-blocking

_ Các hàm thực hiện hoạt động nhập / xuất trên socket trở vền gay sau khi được gởi

_ Phát sinh lỗi WSAEWOULDBLOCK nếu tác vụ yêu cầu chưa hoàn tất → Tiến trình không bị chặn

4 Mô hình xử lý

a) Blocking

_ Sử dụng các hàm socket theo chế độ hoạt động mặc định (blocking)

_ Thường sử dụng giải pháp xử lý đa luồng (multithread)

b) WSAAsyncSelect

_ Mô hình xử lý bất đồng bộ:

• Ứng dụng đăng ký sự kiện mong đợi xảy ra trên socket

• Hệ thống giám sát và gửi thông điệp báo hiệu đến ứng dụng khi sự kiện xảy ra

• Ứng dụng xử lý khi nhận được thông điệp

_ Giải pháp phù hợp với mô hình hoạt động hướng thông điệp của Windows

WSAAsyncSelect (s, hWnd, USER_MESSAGE, FD_READ | FD_CLOSE);

• Sai: Thông điệp báo hiệu do người lập trình định nghĩa

#define <USER_MESSAGE> (WM_USERtn) const UINT <USER_MESSAGE> = WM_USERtn;

Trang 14

c) Tạo trình xử lý thông điệp (MFC)

_ Hàm thành phần của lớp cửa sổ nhận thông điệp:

• Khai báo:

LRESULT <tên trình xử lý> (WPARAM wParam, LPARAM lParam);

trong đó:

 wParam: handle socket xảy ra sự kiện mong đợi

 lParam: mã sự kiện xảy ra và lỗi sai

• Định nghĩa:

LRESULT <tên lớp>::<tên trình xử lý>(WPARAM wParam, LPARAM lParam)

{

if (WSAGETSELECTERROR (lParam == 0) {

switch (WSAGETSELECTEVENT (lParam)) {

case FD_ACCEPT: // ; break;

case FD_READ: // ; break;

case FD_CLOSE: // ; break;

//

} }

else { // } return LRESULT();

}

• Ví dụ:

const UINT MSG_ASYNC = WM_USER + 1;

bool <tên lớp>::ConnectToServer (const Cstring &sIpAddr, short

nServerPort) {

bool bSuccess = true;

m_hSocket = ;

if (m_hSocket != INVALID_SOCKET) {

SOCKADD_IN sockAddr;

if (connect (m_hSocket, , ) == SOCKET_ERROR || WSAAsynSelect (m_hSocket, m_h Wnd, MSG_ASYNC, FD_READ | FD_CLOSE) == SOCKET_ERROR)

{

closesocket (m_hSocket);

bSuccess = false;

} }

else bSuccess = false;

switch (WSAGETSELECTEVENT) {

case FD_READ: ReceiveData(); break;

case FD_CLOSE: closesocket (m_hSocket); break; }

} else { // } return 0L;

} _ Đăng ký trình xử lý:

Trang 15

BEGIN_MESSAGE_MAP(<tên lớp >, <tên lớp cơ sở>)

//

ON_MESSAGE (<thông điệp>, <tên trình xử lý thông điệp>)

END_MESSAGE_MAP

trong đó:

• MSG_ASYNC: thông điệm do người lập trình định nghĩa

• OnAsyncSelect tên trình xử lý thông điệp

 Giao tiếp với người dùng

 Cho phép đăng nhập theo nhóm

 Cho phép “trò chuyện” trong nhóm

_ Giao thức ứng dụng:

• Server port: 2013: có thiết lập cầu nối

• Tập lệnh (Client  Server):

 GLIST: yêu cầu danh sách nhóm :

LOGIN <khoảng trắng (SP)> <tên nhóm>, <tên người dùng>

 ULIST: yêu cầu danh sách người dùng trong nhóm:

 Gửi nội dung trò chuyện:

TALKS <khoảng trắng (SP)><thông điệp>

 LGOUT: đăng xuất

 Ký hiệu đặc biệt để ngăn cắt: CRLF

• Dạng hồi đáp (Server  Client):

 Khi thiết lập cầu nối: xuất lời chào

 Lệnh GLIST (trường hợp thành công):

message = <tên nhóm 1>, …, <tên nhóm N>

 Lệnh ULIST (trường hợp thành công):

message = <tên người dùng 1>, …, <tên người dùng N>

 Lệnh LOGIN, LGOUT, TALKS (hoặc trường hợp thất bại):

message = <nội dung diễn giải>

Trang 16

c) Cài đặt

_ Ứng dụng dạng hộp thoại

_ Lớp hộp thoại ứng dụng:

• Dữ liệu:

 socket handle: SOCKET m_hSocket

 Trạng thái hiện tại:

enum FSTATE {FS_BEGIN, FS_CONNECT, FS_GLIST, FS_LOGIN, FS_ULIST, FS_TALKS, FS_LOGOUT};

FSTATE m_fState

 Tên đăng nhập: Cstring m_sUserName

 Thành phần liên kết với điều khiển:

CString m_sMessage CListBox m_lbGroups CListBox m_lbUsers CListBox m_lbContent

• Thao tác:

 Trình xử lý sự kiện:

 Tác động trên các nút:

 Kết nối (Connect):

 Kiểm tra trạng thái chưa kết nối

 Mở hộp thoại kết nối (Connect Dialog)

 Thực hiện kết nối – gọi thao tác phụ trợ (ConnectToServer)  Đặt trạng thái: đang kết nối

 Hoạt động bất đồng bộ:

 Lấy Danh sách Nhóm (Get Groups):

 Kiểm tra trạng thái kết nối

 Gởi lệnh GLIST

 Đặt trạng thái: đang lấy danh sách nhóm

 Đăng nhập (Login):

 Kiểm tra trạng thái đã kết nối và chưa đăng nhập

 Mở hộp thoại đăng nhập (Login Dialog)

 Gởi lệnh LOGIN

 Đặt trạng thái: đang đăng nhập

 Lấy Danh sách Người dùng (Get Users):

 Kiểm tra trạng thái đã đăng nhập

 Đặt trạng thái: đang trao đổi

 Đăng xuất (Logout):

 Kiểm tra trạng thái đã đăng nhập

 Gởi lệnh LGOUT

 Đặt trạng thái: đang thoát ra khỏi nhóm

 Hoạt động bất đồng bộ:

 Kiểm tra mã báo lỗi

 Thực hiện / gọi tác vụ xử lý sự kiện tương ứng:

 FD_CONNECT: báo kết nối thành công

 FD_READ: nhận và xử lý hồi đáp từ server

 FD_CLOSE: đóng socket  mfState = FS_BEGIN  Thông báo

Trang 17

 Đặt trạng thái: đã kết nối

 Lấy Danh sách Nhóm (Get Groups):

 Kiểm tra mã hồi đáp: nếu thành công thì hiển thị danh sách nhóm

 tách các tên nhóm và đưa vào listbox; nếu thất bại thì hiển thị thông điệp báo lỗi nhận từ server

 Hiển thị thông báo nhận từ server

 Đăng nhập (Login):

 Kiểm tra mã hồi đáp: nếu thành công thì đặt trạng thái đã đăng nhập (sẵn sàng đón nhận thông điệp); nếu thất bại thì đặt trạng thái:

đã kết nối (chưa đăng nhập)

 Hiển thị thông báo nhận từ server

 Lấy Danh sách Người dùng (Get Users):

 Kiểm tra mã hồi đáp: nếu thành công thì hiển thị danh sách người dùng; nếu thất bại thì hiển thị thông điệp báo lỗi nhận từ server

 Đặt trạng thái: sẵn sàng nhận thông điệp

 Tạo cầu nối đến server (ConnectToServer):

 Thông số: [vào] Địa chỉ server (dạng chuỗi), [vào] số hiệu cổng

 Kết quả trả về: nếu thành công là true; nếu thất bại là false

 Thực hiện: Kết nối (hoạt động theo chế độ blocking), chọn chế độ hoạt động bất đồng bộ: FD_READ | FD_CLOSE

 Nhận dữ liệu (ReceiveData):

 Xử lý nhận dữ liệu: nội dung hồi đáp từ server

 Gọi thao tác xử lý hồi đáp tương ứng, tùy thuộc trạng thái hiện tại của client

 Gởi dữ liệu (SendData)

 socket handle: SOCKET m_hSocket

 Tên đăng nhập: CString m_sName

 Địa chỉ, cổng phía kết nối:

Trang 18

 Thao tác:

 Thêm người dùng

 Lấy người dùng ra khỏi nhóm

 Tìm người dùng

 Truy xuất tên nhóm

 Lấy danh sách tên nhóm

 Theo socket handle

 Tìm nhóm và người dùng: theo socket handle

 Lấy danh sách tên nhóm

_ Lớp hộp thoại ứng dụng:

• Dữ liệu:

 socket handle – “lắng nghe”

 Danh sách nhóm: CGroupList m_groupList

 Danh sách người dùng mới kết nối: CUserList m_groupNewUsers

 Thành phần liên kết với các điều khiển

• Thao tác:

 Khởi tạo:

 Thông số: port lắng nghe

 Kết quả trả về: nếu thành công là socket handle; nếu thất bại là INVALID_SOCKET

 Dữ liệu nhóm: gồm tập tin dữ liệu hoặc cơ sở dữ liệu

 Socket “lắng nghe” – InitListenSocket:

Socket() Bind() Listen() WSAAsyncSelect() - FD_ACCEPT

 Kiểm tra người dùng chưa đăng nhập

Kiểm tra thông tin đăng nhập:

 Tên nhóm có thật:

 Tên người dùng không trùng lắp

 Chuyển người dùng sang nhóm đăng nhập (trường hợp thành công):

 Xóa khỏi danh sách người dùng mới kết nối

 Thêm vào danh sách người dùng của nhóm đăng nhập

Trang 19

 Tạo nội dung hồi đáp theo quy định (sử dụng thao tác lấy danh sách tên người dùng của CUserGroup)

 Xóa khỏi danh sách người dùng mới của nhóm

 Thêm vào danh sách người dùng mới kết nối

 Tạo hồi đáp theo quy định

SOCKETADD_IN sockAddr;

sockAddr.sin_family = … sockAddr.sin_port = htons (nServerPort);

if (isalpha (sServerAddress[0]) {

PHOSTENT pHost = gethostbyname (sServerAddress);

if (pHost) memcpy (&sockAddr.sin_addr, pHost->h_addr, 4); }

else sockAddr.sin_addr = inet_addr (sServerAddress);

if (connect (m_hSocket, (LPSOCKADDR) & sockAddr, sizeof(sockAddr)) == SOCKET_ERROR || WSAAsyncSelect, FDREAD

| FDCLOSE) == SOCKET_ERROR) {

closesocket (m_hSocket);

bSuccess = false;

} else bSuccess = false;

return bSuccess;

} }

Trang 20

if (ConnectToServer (dlg.m_nServerAddress) == dlg.m_nServerPort)

{

mlbContent.AddString (_T(“Đã kết nối”));

m_fState = FS_CONNECT;

} else mlbContent.AddString (_T(“Kết nối thất bại”)); }

} }

_ Trình xử lý cho hoạt động xử lý bất đồng bộ:

• Hàm thành phần của C…Dlg (lớp hộp thoại chính của ứng dụng)

LRESULT C…Dlg::OnAsyncSelect (WPARAM wParam, LPARAM lParam) {

if (WSAGETSELECTERROR (lParam) == 0) {

switch (WSAGETSELECT (lParam)) {

case FD_READ: ReceiveData(); break;

char szBuffer[BUF_LEN + 1];

int nRecvBytes = recv (m_hSocket, szBuffer, BUF_LEN , 0);

if (nRecvBytes > 0) {

Ngày đăng: 19/10/2014, 12:58

TỪ KHÓA LIÊN QUAN