Chương 1. Tổng quan lập trình Windows (4LT +
1BT)
• Chương 2. Lập trình Windows VC++/MFC (15LT +
6BT)
• Chương 3. Một số chủ đề nâng cao
– Tạo thư viện liên kết động (DLL) (3LT + 2BT)
– Luồng (Thread) (3LT + 2BT)
– Windows Socket (2LT + 2BT)
• Chương 4. X}y dựng ứng dụng Windows Form (3LT
+ 2BT)
• Bài tập lớn
84 trang |
Chia sẻ: Mr Hưng | Lượt xem: 974 | Lượt tải: 0
Bạn đang xem trước 20 trang nội dung tài liệu Kỹ thuật máy tính - Lập trình windows, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
hể chia sẻ m~ lệnh).
• Khi không còn sử dụng, có thể giải phóng DLL khỏi
bộ nhớ
• Khi cần n}ng cấp, chỉ cần thay thế file DLL, c|c file
chương trình kh|c không bị ảnh hưởng.
• Có thể viết bằng nhiều ngôn ngữ lập trình
• Nhược điểm: Lập trình xử lý nhiều thao t|c phức
tạp hơn.
240Lập trình Windows
61
Nội dung DLL
• M~ lệnh của c|c h{m (functions)
• C|c lớp (Classes)
• Biến to{n cục (global variables)
• Resource (bitmap, font)
• Ví dụ: Solitaire game sử dụng Cards.dll chứa
cards images + functions
• Chỉ những thành phần được export của
DLL mới có thể được truy xuất từ bên
ngoài.
241Lập trình Windows
Hàm DllMain()
• DLL không thực thi như một chương trình
độc lập, nhưng có chứa h{m main đặc biệt
gọi l{ DllMain().
• Được gọi bởi Windows khi nó được nạp v{o
bộ nhớ lần đầu tiên. Để thực hiện khởi tạo
trước khi sử dụng nội dung của DLL.
• Cũng được gọi khi giải phóng khỏi bộ nhớ để
thực hiện những giải phóng cần thiết.
242Lập trình Windows
3.1.2. Ph}n loại DLLs
• Có 3 loại: (trong MFC)
– DLL mở rộng (MFC Extension DLL)
– DLL thông thường với liên kết tĩnh MFC
(Regular DLL with MFC statically linked).
– DLL thông thường với liên kết động MFC
(Regular DLL with MFC dynamically linked)
243Lập trình Windows
MFC Extension DLL
• Cho phép sử dụng c|c lớp (trong DLL) dẫn xuất từ
c|c lớp MFC.
• Cho phép ứng dụng dùng DLL có thể sử dụng c|c
lớp của nó.
• MFC Extension DLL liên kết với c|c DLL của MFC
theo dạng liên kết động.
• C|c DLLs dạng n{y chỉ sử dụng cho ứng dụng MFC
có tính năng “Use MFC in a Shared DLL”
• Không dùng được bởi c|c ứng dụng sử dụng liên kết
tĩnh đến thư viện MFC (Statically linked to MFC)
244Lập trình Windows
62
Regular DLL – Statically linked to MFC
• L{ c|c DLL sử dụng c|c lớp của MFC dưới dạng liên
kết tĩnh. (c|c đoạn m~ trong DLL của MFC được
chèn v{o Regular DLL mỗi khi h{m tương ứng được
sử dụng đến). L{m cho Regular DLL kiểu n{y có
kích thước lớn.
• Có thể được sử dụng bởi c|c ứng dụng MFC hoặc
Win32 Application (không cần môi trường MFC)
• Chỉ cho export c|c h{m, không cho export c|c lớp
có trong DLL.
245Lập trình Windows
Regular DLL – Dynamically linked to MFC
• L{ DLL sử dụng c|c lớp MFC dạng liên kết
động (không thêm m~ lệnh của lớp MFC v{o
DLL n{y, chỉ gọi đến khi được dùng).
• Kích thước giảm so với kiểu Regular DLL liên
kết tĩnh MFC.
• Có thể được sử dụng bởi ứng dụng MFC hoặc
bất kỳ ứng dụng Win32 (nhưng cần có DLL
của MFC tương ứng đi kèm)
246Lập trình Windows
3.1.3. C|ch gọi DLL trong ứng dụng
• 2 kiểu:
– Gọi lúc ứng dụng được nạp (load time dynamic
linking hay early binding).
– Gọi lúc thực thi (runtime dynamic linking hay
late binding)
247Lập trình Windows
Gọi lúc ứng dụng được nạp (load time)
• DLL được nạp v{o bộ nhớ khi ứng dụng sử
dụng nó được nạp v{o bộ nhớ để thực thi.
• DLL được nạp ngay từ đầu bất kể ứng dụng
yêu cầu nạp nó có sử dụng đến c|c h{m của
nó trong qu| trình thực thi hay không.
• Liên kết đến c|c h{m DLL muốn dùng được
thiết lập ngay từ đầu.
• Có thể bất tiện: Tốn bộ nhớ nạp DLL, ứng
dụng có thể không hoạt động nếu DLL yêu
cầu nạp không tồn tại.
248Lập trình Windows
63
Gọi lúc thực thi (run time)
• Lập trình viên quyết định khi n{o cần nạp DLL lên
bộ nhớ. (Được nạp khi có một h{m của DLL được
ứng dụng yêu cầu sử dụng).
• Khó khăn: Tốn công sức lập trình cho việc nạp DLL,
gọi h{m DLL.
– Cần dùng h{m API LoadLibrary() để nạp DLL khi nó
được yêu cầu.
– Hàm GetProcAddress() để lấy địa chỉ h{m (con trỏ h{m)
của h{m DLL cần dùng.
– Hàm FreeLibrary() để deattach DLL khi ứng dụng không
còn dùng đến. (DLL sẽ được giải phóng khi không còn
ứng dụng n{o dùng đến)
249Lập trình Windows 250Lập trình Windows
Minh họa gọi DLL lúc
thực thi ứng dụng
3.1.4. Viết DLL
• Minh họa x}y dựng một Regular DLL (dạng
liên kết động với MFC)
• DLL n{y chứa 2 h{m tính to|n (cộng v{ nh}n)
cho phép ứng dụng kh|c gọi đến.
• Tạo Project MFC/MFC DLL
• Chọn kiểu Regular DLL using shared MFC
DLL
251Lập trình Windows
Minh họa viết DLLRegular
252Lập trình Windows
64
Khai b|o h{m xuất
253Lập trình Windows
• Khai b|o h{m xuất đặt trong tệp tin .cpp hoặc
.h
• H{m nội bộ của DLL khai b|o v{ triển khai
như h{m của ứng dụng thông thường
254Lập trình Windows
Thực thi h{m xuất
• Đặt macro AFX_MANGE_STATE đầu tiên
trong thân hàm.
255Lập trình Windows
//TODO: If this DLL is dynamically linked against the MFC DLLs,
// any functions exported from this DLL which call into
// MFC must have the AFX_MANAGE_STATE macro added at the
// very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
Thực thi h{m xuất (minh họa)
• Phần thực thi h{m cộng:
• Phần thực thi h{m nh}n:
256Lập trình Windows
65
Biên dịch DLL
• Như biên dịch ứng dụng thông thường
• Tập tin kết quả: .dll v{ .lib
• C|c ứng dụng sử dụng dll n{y cần dùng đến 2
tập tin trên.
257Lập trình Windows
3.1.5. Minh họa ứng dụng sử dụng DLL
• Gọi DLLRegular đ~ viết lúc nạp ứng dụng (load
time)
• Tạo ứng dụng đơn giản (kiểu dialog base)
• Chứa tập tin .dll v{ .lib cùng thư mục project
• Add tập tin .lib v{o Project
258Lập trình Windows
Khai b|o c|c h{m import trong ứng dụng
• Muốn sử dụng h{m xuất (export) n{o từ DLL,
ứng dụng sẽ khai b|o import cho h{m đó.
• Dạng khai b|o tổng qu|t
259Lập trình Windows
Viết m~ thực thi cho c|c chức năng
• Viết m~ xử lý nút cộng, nh}n gọi h{m cong,
nhan tương ứng của DLL
• Ví dụ: H{m xử lý sự kiện click chuột nút cộng
260Lập trình Windows
66
Minh họa ứng dụng gọi DLL kiểu runtime
• C|ch thức nạp h{m từ DLL:
– Nạp DLL bằng h{m LoadLibrary. Kiểm tra xem
DLL có tồn tại không bằng c|ch xem kết quả trả
về có kh|c NULL hay không
– Nạp h{m cần thiết bằng h{m GetProcAddress.
Kiểm tra việc gọi h{m th{nh công hay không.
– Giải phóng DLL khỏi bộ nhớ bằng h{m
FreeLibrary.
261Lập trình Windows
Ứng dụng gọi DLL kiểu Run time
• Khai b|o con trỏ h{m cho h{m muốn import
v{o ứng dụng. (Phụ thuộc v{o h{m export
trong DLL)
• Với ví dụ DLLRegular, h{m xuất có dạng:
• Định nghĩa con trỏ h{m cho 2 h{m n{y:
262Lập trình Windows
C|ch thức nạp h{m từ DLL
263Lập trình Windows
Ví dụ: Gọi h{m nh}n
264Lập trình Windows
67
Thử nghiệm cho c|ch gọi kiểu run time
• Không chép file .dll v{o cùng thư mục ứng
dụng sử dụng dll. Chạy ứng dụng được không
? Có thực thi được c|c chức năng (cộng,
nh}n) của ứng dụng không ?
• Không tắt ứng dụng, chép file .dll v{o cùng
thư mục ứng dụng. Thực thi được c|c chức
năng của ứng dụng không ?
265Lập trình Windows
Ex-3.? DLL
• Viết một Extension DLL cho ứng dụng
Sketcher
266Lập trình Windows
3.2. Thread (Tiểu trình/Luồng)
• 3.2.1. Một số kh|i niệm
• 3.2.2. Lập trình đa luồng
• 3.2.3. Tạo Worker Thread
• 3.2.4. Tạo UI Thread
• 3.2.5. Kết thúc một Thread
• 3.2.6. Đồng bộ c|c Thread
• 3.2.7. Ví dụ minh họa
267Lập trình Windows
3.2.1. Một số kh|i niệm (1)
• Trên Windows, mỗi ứng dụng đang chạy l{ một tiến
trình (Process)
• Một tiến trình có thể chứa một hoặc nhiều tiểu
trình/hay luồng (thread) thực thi. (path of execution)
268Lập trình Windows
• Main Thread/
Primary Thread: là
thread chính/mặc định
của một ứng dụng.
• Secondary Thread: các
thread kh|c (nếu
chương trình được lập
trình tạo thêm thread)
68
Một số kh|i niệm (2)
• Multithreading: Nhiều thread cùng chạy đồng thời
(Được Windows lập lịch - schedule)
• Hệ điều h{nh ph}n chia thời gian CPU cho c|c
thread – cơ chế đa nhiệm (multitasking)
• Tại sao cần đa luồng ?
– Ứng dụng muốn thực hiện nhiều nhiệm vụ đồng thời.
– Thường c|c nhiệm vụ xử lý được chạy “hậu cảnh”
(background) trong khi c|c xử lý tương t|c người dùng
chạy “tiền cảnh” (foreground)
– Ví dụ: ứng dụng MS Word với thread check spelling
grammar.
269Lập trình Windows
3.2.2. Lập trình đa luồng
• Lập trình đa luồng (multithreading programming):
– Multithreading in pure C
– Multithreading in Win32 API
– Multithreading in MFC
• Lớp CWinThread: lớp cơ sở đóng gói c|c hoạt động
thực thi của thread.
• MFC ph}n biệt 2 loại thread:
– Worker Thread (Tiểu trình xử lý nội): hỗ trợ thực hiện
c|c xử lý bên trong, “hậu cảnh” (background).
– User Interface Thread (Tiểu trình giao diện): trực tiếp
tiếp nhận yêu cầu người dùng (cơ chế Windows
Messages)
270Lập trình Windows
Lớp CWinThread
• Data members
– m_hThread: The current thread handle
– m_nThreadID: The current thread ID
– m_bAutoDelete:
(TRUE/FALSE) thread được thiết lập tự động giải phóng hoặc không.
• Data Functions:
– CreateThread: Bắt đầu thực thi thread
– SuspendThread: Tạm dừng/ngưng một thread (tăng biến đếm số
lần suspend)
– ResumeThread: Tiếp tục một thread bị tạm dừng (giảm biến đếm số
lần suspend).
– SetThreadPriority: Thiết lập mức độ ưu tiến của thread (tương đối
so với mức độ ưu tiên của process) ( LOW, BELOW LOW or HIGH)
– GetThreadPriority: Lấy mức độ ưu tiên của thread.
271Lập trình Windows
CObject
CCmdTarget
CWinThread
CWinApp
3.2.3. Tạo Worker Thread
• H{m to{n cục AfxBeginThread, bắt đầu một thread
trong MFC
• Có 2 dạng cho 2 kiểu thread.
• Cú ph|p dạng tạo Worker Thread:
– 2 tham số đầu: quan trọng
– 4 tham số sau: tùy chọn (có thể sử dụng hoặc không)
272Lập trình Windows
CWinThread* AfxBeginThread( AFX_THREADPROC ThreadProc,
LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0, DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
69
Tạo Worker Thread (2)
273Lập trình Windows
• Ý nghĩa c|c tham số h{m AfxBeginThread
Các tham số Mô tả
ThreadProc
controlling function, cannot be NULL. This function must be declared
as follows: UINT MyControllingFunction( LPVOID pParam );
pParam
Parameter to be passed to the controlling function as shown in the
parameter to the function declaration in pfnThreadProc.
nPriority Thread priority.
nStackSize
Specifies the size in bytes of the stack for the new thread. If 0, the
stack size defaults to the same size stack as the creating thread.
dwCreateFlags
additional flag and can be any of these two CREATE_SUSPENDED or
0. CREATE_SUSPENDED starts the thread with a suspend count of
one. The thread will not execute until ResumeThread is called. 0
Start the thread immediately after creation.
lpSecurityAttrs
Points to a SECURITY_ATTRIBUTES structure. See
SECURITY_ATTRIBUTES for more details.
Thread Function (1)
• H{m thực thi của một thread (Thread
Function/ThreadProc)
• L{ h{m callback (Được gọi bởi hệ điều h{nh), cần
khai b|o static hoặc to{n cục (bên ngo{i c|c lớp).
• Có dạng:
• pParam l{ con trỏ đến 1 cấu trúc dữ liệu của thread
do người lập trình định nghĩa. Được truyền cho
h{m thông qua tham số thứ 2 của h{m
AfxBeginThread
274Lập trình Windows
UINT ThreadFunc (LPVOID pParam)
Thread Function (2)
• Ví dụ:
275Lập trình Windows
CWinThread *pThread =
AfxBeginThread( ThreadFunction, &data);
UINT ThreadFunction(LPVOID param) {
UINT nIterations = (UINT) pParam;
for (int i=0; i<nIterations; i++);
//do something
return 0;
}
Thread Priorities (1)
• C|c tiến trình (process) được hệ điều h{nh lập lịch
thực thi với cấp độ ưu tiên kh|c nhau (chiếm thời
gian CPU kh|c nhau). Bao gồm:
REALTIME_PRIORITY_CLASS
HIGH_PRIORITY_CLASS
NORMAL_PRIORITY_CLASS
IDLE_PRIORITY_CLASS
• Cấp độ ưu tiên của tiến trình được thiết lập tương
đối với c|c độ ưu tiên của process nó thuộc về.
• Có thể thiết lập khi gọi h{m AfxBeginThread( ),
hoặc dùng h{m: CWinThread::SetThreadPriority
276Lập trình Windows
70
Thread Priorities (2)
277Lập trình Windows
THREAD_PRIORITY_TIME_CRITICAL
Normal for HIGH, NORMAL, or
IDLE. Double for REALTIME.
THREAD_PRIORITY_HIGHEST = Process Priority + 2.
THREAD_PRIORITY_ABOVE_NORMAL = Process Priority +1.
THREAD_PRIORITY_NORMAL = Process Priority.
THREAD_PRIORITY_BELOW_NORMAL = Process Priority -1.
THREAD_PRIORITY_LOWEST = Process Priority -2.
THREAD_PRIORITY_IDLE
Normal for REALTIME, 1 for
HIGH, NORMAL,
Suspending and Resuming Threads
• Mỗi thread có thể chuyển đổi qua c|c nhiều trạng th|i hoạt
động như sơ đồ.
• Tạm ngừng: H{m SuspendThread
• Khôi phục: H{m ResumeThread
• Trạng th|i “ngủ”: H{m Sleep
278Lập trình Windows
CWinThread* pThread =
AfxBeginThread (ThreadFunc,
&threadInfo,
THREAD_PRIORITY_NORMAL, 0,
CREATE_SUSPENDED);
pThread->ResumeThread ();
// Start the thread
3.2.4. Tạo User Interface Thread (1)
• UI Thread có giao diện GUI với vòng lặp thông điệp
(message loop).
• C|c bước chính tạo UI Thread:
– Tạo lớp dẫn xuất từ CWinThread v{ override c|c h{m:
279Lập trình Windows
Function name Purpose
InitInstance Perform thread instance initialization. Must be overridden.
Run
Controlling function for the thread. Contains the message pump.
Rarely overridden.
OnIdle Perform thread-specific idle-time processing. Not usually overridden.
PreTranslateMessage
Filter messages before they are dispatched to TranslateMessage and
DispatchMessage. Not usually overridden.
ProcessWndProcExcept
ion
Intercept unhandled exceptions thrown by the thread's message and
command handlers. Not usually overridden.
ExitInstance Perform cleanup when thread terminates. Usually overridden.
Tạo User Interface Thread (2)
– Gọi h{m AfxBeginThread cho UI Thread
– Tham số đầu tiên l{ con trỏ lớp Thread dẫn xuất
đ~ tạo.
– C|c tham số còn lại l{ tùy chọn (có thể dùng hoặc
không)
280Lập trình Windows
CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass,
int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0,
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );
71
3.2.5. Kết thúc một Thread
• Với Worker Thread: 2 trường hợp kết thúc:
– Khi h{m thực thi của thread (ThreadFunction)
kết thúc (trả về return)
– Khi có h{m ở bất kỳ đ}u gọi h{m kết thúc thread
AfxEndThread() (h{m to{n cục)
281Lập trình Windows
CwinThread *pThread = AfxBeginThread(ThreadFunction, &data);
UINT ThreadFunction(LPVOID param) {
DWORD result =0 ;
// do somthing
AfxEndThread(exitCode);
return result;
}
Kết thúc một Thread (2)
• Với UI Thread:
– Kết thúc khi có thông điệp WM_QUIT gửi đến
h{ng đợi thông điệp của nó.
– Hoặc khi bản th}n thread gọi h{m AfxEndThread
• Khi kết thúc trả về m~ (exit code 32 bit), có thể
kiểm tra m~ n{y:
282Lập trình Windows
DWORD dwExitCode;
::GetExitCodeThread (pThread->m_hThread, &dwExitCode);
if (dwExitCode == STILL_ACTIVE) {
// The thread is still running. }
else { // The thread has terminated. Delete the CWinThread object.
delete pThread;
}
3.2.6. Đồng bộ c|c thread
• Thread Synchronization
• Vấn đề ?
• Giải ph|p ?
• Windows cung cấp 4 cơ chế đồng bộ c|c thread:
– Critical sections
– Mutexes
– Events
– Semaphores
• T{i liệu:
– Chapter 17, Programming Windows with MFC
– MSDN
283Lập trình Windows
3.2.7. Ví dụ Thread
• C|c ví dụ đơn giản minh họa sử dụng thread dùng
Win32 API, MFC
• Minh họa Worker Thread
– Tiểu trình xử lý nội (Worker Thread) c{i đặt một h{m có
nhiệm vụ thực hiện chạy chữ trong dòng thông b|o cho
đến khi có tín hiệu ngừng.
– Tiểu trình chính của ứng dụng thực hiện giao tiếp người
dùng.
Nút Start/Stop, Close
284Lập trình Windows
72
Ex3-?. Prime Sieve
• X}y dựng ứng dụng s{ng số nguyên tố (Prime
Sieve) với tiểu trình xử lý nội (Worker
Thread) cho việc xử lý giải thuật s{ng số
nguyên tố.
285Lập trình Windows
3.3. Lập trình Windows Socket
• 3.3.1. Giới thiệu chung
• 3.3.2. Lập trình Winsock
• 3.3.3. Lập trình MFC Socket
• 3.3.4. Ví dụ minh họa
286Lập trình Windows
3.3.1. Giới thiệu chung
• Winsock:
– Thư viện liên kết động của Microsoft, ph}n phối
trên Windows OS
– Cung cấp API ph|t triển ứng dụng mạng
– Có thể sử dụng nhiều ngôn ngữ lập trình. Thông
thường kết hợp C/C++ v{ Winsock
• MFC Socket:
– Thư viện lớp (MFC) của Microsoft, đi kèm bộ
công cụ ph|t triển Visual C++
287Lập trình Windows
Giới thiệu chung (tt)
• Winsock:
– Xuất xứ từ BSD (Berkeley Software Distribution –
UNIX)
– Ver 1.0 (1992), Hiện nay l{ phiên bản Winsock 2
tích hợp trong tất cả c|c phiên bản Windows OS
– Gồm nhiều tầng, trong đó giao tiếp trực tiếp với
ứng dụng l{ thư viện ws2_32.dll.
– Cung cấp giao diện dịch vụ trên nền bộ giao thức
TCP/IP
288Lập trình Windows
73
Giới thiệu chung (tt)
• Socket ? (= IP + Port)
– Điểm truyền thông đầu cuối cho phép ứng dụng
gửi v{ nhận c|c gói tin qua đường truyền mạng.
– Cung cấp giao diện để một chương trình kết nối,
trao đổi dữ liệu với một chương trình trên một
m|y tính kh|c trong mạng
289Lập trình Windows
Giới thiệu chung (3)
• C|c loại Socket:
– Datagram socket – sử dụng
UDP
• Ít tin cậy
• Không gửi lại
• Không kết nối (Connectionless)
– Stream socket – using TCP
• Tin cậy
• Có gửi lại
• Hướng kết nối (Connection-
oriented)
– Raw and others
290Lập trình Windows
Lập trình Socket trên Windows
• 2 phương |n:
– Lập trình Winsock: Ứng dụng Win 32. Sử dụng
trực tiếp thư viện Winsock (C|c h{m Winsock
API)
– Lập trình MFC Socket: Ứng dụng MFC. Sử dụng
c|c lớp MFC cung cấp hỗ trợ Winsock (đóng gói
các hàm Winsock API):
• Lớp CAsyncSocket
• Lớp CSocket
291Lập trình Windows
3.3.2. Lập trình Winsock
• C|c thao t|c cơ bản liên quan Winsock v{
TCP/IP:
– Khởi tạo Winsock
– X}y dựng TCP Server, TCP Client
292Lập trình Windows
74
Lập trình Winsock
• Thư viện: Winsock 2 bao gồm thư viện liên kết
động WS2_32.DLL, tệp tiêu đề WINSOCK2.H, tệp
thư viện WS2_32.LIB.
• X}y dựng ứng dụng Win 32
• Khai b|o thư viện winsock2.h v{ file .lib (ws2_2.lib)
293Lập trình Windows
#include
#pragma comment (lib,"ws2_32.lib")
Khởi tạo Winsock
• Tham số:
– wVersionRequested l{ phiên bản thư viện
Winsock muốn nạp. Sử dụng Macro
MAKEWORD(x,y) sử dụng để tạo ra WORD
cần thiết, với x l{ byte thấp, y l{ byte cao của
số hiệu phiên bản.
– lpWSAData l{ con trỏ tới cấu trúc WSAData (ý
nghĩa xem MSDN)
294Lập trình Windows
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData);
Giải phóng Winsock
• Khi ứng dụng đã sử dụng xong Winsock, nó
có thể giải phóng Winsock bằng lệnh
WSACleanup. Lệnh n{y sẽ giải phóng mọi
t{i nguyên Winsock sử dụng, hủy c|c lệnh
v{o ra còn dang dở.
• Nguyên mẫu hàm:
int WSACleanup(void);
Trả về 0 nếu th{nh công, tr|i lại trả về
SOCKET_ERROR (chi tiết lỗi dùng h{m
WSAGetLastError)
295Lập trình Windows
Ví dụ khởi tạo Winsock
296Lập trình Windows
#include "stdafx.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA SData;
int iResult = WSAStartup(0x0202,&SData); //MAKEWORD(2,2)
if (iResult!=0){
cout << "KHONG THE KHOI DONG WINSOCK";
return 1;
}
cout << "KHOI TAO SOCKET THANH CONG: \n";
cout << "Phien ban: "<< SData.wVersion << "\n";
cout << "Phien ban co the ho tro: "<< SData.wHighVersion <<
"\n";
cout << "Ghi chu: " << SData.szDescription << "\n";
cout << "Thong tin cau hinh: " << SData.szSystemStatus << "\n";
WSACleanup();
return 0;
}
75
X|c định địa chỉ
• Địa chỉ m|y đích: x|c định bởi IP + Port No.
• Winsock cung cấp cấu trúc để chứa thông tin
địa chỉ:
297Lập trình Windows
struct sockaddr_in
{
short sin_family; //=AF_INET họ địa chỉ IP
u_short sin_port; //Số hiệu cổng kết nối đến
struct in_addr sin_addr; //Địa chỉ IP m|y đích
char sin_zero[8];
};
Ví dụ x|c định địa chỉ
298Lập trình Windows
SOCKADDR_IN InternetAddr; // Khai báo cấu trúc
địa chỉ
INT nPortId = 8888; // Khai báo cổng
InternetAddr.sin_family = AF_INET;// Họ địa chỉ
Internet
//Chuyển xâu địa chỉ 136.149.3.29 sang số 4 byte dạng
network-byte order và gán cho trường sin_addr
InternetAddr.sin_addr.s_addr =
inet_addr("136.149.3.29");
//Chuyển đổi cổng sang dạng network-byte order và gán
cho trường sin_port
InternetAddr.sin_port = htons(nPortId);
Tạo Socket
• Sau khi đã có đầy đủ thông tin về máy đích,
viêc đầu tiên cần làm để kết nối đến l{ tạo
một socket (tạo một cổng kết nối ảo từ m|y
cục bộ nối tới máy đích)
• Cú pháp:
299Lập trình Windows
SOCKET socket (
int af,
int type,
int protocol
);
Tạo socket (tt)
• C|c tham số:
– af (Address Family) xác định họ socket,
AF_INET cho IPv4
– type: Kiểu socket có 2 loại: SOCK_STREAM cho
TCP/IP và SOCK_DGRAM cho UDP/IP.
– Protocol: x|c định giao thức sử dụng cho tầng
giao vận, với TCP sẽ l{ IPPROTO_TCP, với UDP l{
IPPROTO_UDP.
• Ví dụ tạo socket TCP
300Lập trình Windows
SOCKET s;
s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)
76
Truyền nhận dữ liệu
• C|c bước tiếp theo để truyền nhận dữ liệu phụ
thuộc v{o loại giao thức Socket được khởi tạo (TCP
hay UDP), ứng dụng phía Server/phía Client.
• Sử dụng c|c h{m tiếp theo Winsock:
301
Hàm Winsock Ý nghĩa
Bind attach a local address to a socket
Listen announce a willingness to accept connections
Accept block the caller process until a connection attempt arrives
Connect actively attempt to establish a connection
Send send some data over the connection
Recv receive some data from the connection
Close release the connection (the port)
Mô hình truyền nhận
dữ liệu với Socket TCP
Mô hình truyền nhận
dữ liệu với Socket UDP
Hàm bind( )
int bind(
SOCKET s,
const struct sockaddr FAR* name,
int namelen
);
Tác dụng dụng của BIND là sẽ giúp cho SOCKET của
SERVER biết rằng nó sẽ chờ đợi kết nối và nhận dữ
liệu trên IP nào và PORT bao nhiêu?
Hàm Bind gồm có 3 thông số:
- SOCKET s: Socket được thiết lập
- sockaddr name: Cấu trúc ADDR bao gồm địa chỉ IP
và PORT
- int namelen: Kích thước của cấu trúc sockaddr
304Lập trình Windows
77
Hàm listen( )
• int listen(
SOCKET s,
int backlog
);
•
Kể từ khi gọi hàm này thì SERVER sẽ bắt đầu lắng
nghe kết nối của mình.
Hàm LISTEN gồm có 2 thông số:
- SOCKET s: Socket đ~ được thiết lập IP và PORT.
- int backlog: Số kết nối cho phép chờ trong hàng đợi
khi Server chưa chấp nhận kết nối. (vì đôi lúc có thể
có tới 2 hay 3 client kết nối tới cùng 1 lúc). Giá trị tốt
nhất là khoảng từ 5 – 10.
305Lập trình Windows
Hàm Connect
• H{m được gọi từ CLIENT nếu nó muốn kết nối tới
SERVER
- SOCKET s: Socket đ~ được khởi tạo.
- sockaddr *serv_addr: IP v{ PORT của Server.
- int addrlen: Sizeof của cấu trúc sockaddr.
306Lập trình Windows
int connect(
SOCKET s,
struct sockaddr *serv_addr,
int addrlen );
Hàm Accept
• Chấp nhận một kết nối đến
• Tham số:
- SOCKET s: Socket lắng nghe của SERVER.
- sockaddr addr: Là cấu trúc sockaddr lưu địa chỉ IP và PORT của CLIENT
kết nối tới SERVER.
- int addrlen: Kích thước cấu trúc địa chỉ IP này.
• Trả về: 1 SOCKET mới
Socket mới được tạo này đại diện cho 1 Connection (kết nối) mới giữa
Server và Client. Sau khi đ~ truyền dữ liệu thì ta phải đóng SOCKET này
lại bằng hàm close như closesocket(connect);
307Lập trình Windows
SOCKET accept(
SOCKET s,
struct sockaddr FAR* addr,
int FAR* addrlen
);
Hàm send
• Gửi dữ liệu giao thức TCP
SOCKET s: L{ SOCKET được tạo ra khi Server chấp nhận
kết nối từ CLIENT
char FAR* buf: L{ bộ đệm dữ liệu (dạng BYTE – char) gửi.
int len: Kích thước của dữ liệu.
int flags: Một số cờ hiệu đi kèm (thông thường l{ 0).
308Lập trình Windows
int send(
SOCKET s,
const char FAR * buf,
int len,
int flags
);
78
Hàm recv
• Nhận dữ liệu trên giao thức TCP
- SOCKET s: L{ SOCKET được tạo ra khi Server chấp nhận
kết nối từ CLIENT
- char FAR* buf: L{ bộ đệm dữ liệu (dạng BYTE – char)
nhận.
- int len: Kích thước của dữ liệu.
- int flags: Một số cờ hiệu đi kèm (thông thường l{ 0).
int recv(
SOCKET s,
char FAR* buf,
int len,
int flags
);
309Lập trình Windows
REVCFROM/SENDTO
• Được sử dụng trên giao thức UDP
• Các thông số:
- SOCKET s: Là SOCKET được tạo ra ban đầu.
- char FAR* buf: Là dữ liệu (dạng BYTE – char) nhận
- int len: Kích thước của dữ liệu nhận.
- int flags: Một số cờ hiệu đi kèm (thông thường là 0).
- sockaddr *from: IP và PORT từ bên gửi.
- int *fromlen: Sizeof cấu trúc addr.
310Lập trình Windows
int recvfrom(
SOCKET s,
char FAR* buf,
int len,
int flags,
struct sockaddr *from,
int *fromlen);
REVCFROM/SENDTO
• - SOCKET s: Là SOCKET được tạo ra ban đầu.
- char FAR* buf: Là dữ liệu (dạng BYTE – char) gửi
- int len: Kích thước của dữ liệu gửi.
- int flags: Một số cờ hiệu đi kèm (thông thường là 0).
- sockaddr *to: IP và PORT tới bên nhận.
- int tolen: Sizeof cấu trúc addr.
311Lập trình Windows
int sendto(
SOCKET s,
const char FAR *buf,
int len,
int flags,
const struct sockaddr* to,
int tolen
);
Close/Shutdown
• int shutdown(
SOCKET s,
int how
);
• int closesocket (SOCKET s);
Hủy SOCKET sau một kết nối hoặc kết thúc chương
trình.
Tham số how của shutdown:
- SD_RECEIVE: Đóng SOCKET, không cho phép NHẬN
nhưng cho phép GỬI.
- SD_SEND: Đóng SOCKET, kh
Các file đính kèm theo tài liệu này:
- ltwindows2011_5438.pdf