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

[VC++] Lập Trình Mạng Với Thư Viện Winsock pps

38 383 2

Đ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 38
Dung lượng 766,34 KB

Nội dung

[VC++] Lập Trình Mạng Với Thư Viện Winsock [VC++] Lập Trình Mạng Với Thư Viện Winsock I. KHỞI ĐỘNG WINSOCK Để lập trình được Winsock chúng ta sẽ khai báo thư viện winsock2.h (chứa các prototypes) và 1 file lib (chính là file .cpp đã được biên dịch thành .lib) có tên là ws2_2.lib. Bây giờ hãy tạo 1 project Windows32 Console Project. Lưu ý: Chúng ta không khai báo trong file .cpp có hàm main mà khai báo trong file stdafx.h. Đây là cách khai báo thư viện của Visual C++. #include <tchar.h> #include <winsock2.h> #pragma comment (lib,"ws2_32.lib") Và bây giờ sẽ là những hàm để khởi tạo Winsock: int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData); Trong đó: - wVersionRequested là phiên bản thư viện mà mình sử dụng. Ở đây sẽ là giá trị 0x0202 có nghĩa là phiên bản 2.2. Chúng ta có thể dùng macro MAKEWORD(2,2) để trả về giá trị 0x0202. - lpWSData là một số thông tin bổ sung sẽ được trả về sau khi gọi khởi tạo Winsock.: typedef struct WSAData { WORD wVersion; // Phiên bản hiện tại WORD wHighVersion; // Phiên bản có thể hỗ trợ char szDescription[WSADESCRIPTION_LEN + 1]; // Ghi chú char szSystemStatus[WSASYS_STATUS_LEN + 1]; // Trạng thái hệ thống unsigned short iMaxSockets; // Không sử dụng từ Version 2 trở đi unsigned short iMaxUdpDg; // Không sử dụng từ Version 2 trở đi char FAR * lpVendorInfo; // Không sử dụng từ Version 2 trở đi } WSADATA, FAR * LPWSADATA; Và cuối cùng là hàm hủy Winsock khi kết thúc chương trình. nt WSACleanup (void); Chương trình đầu tiên: #include "stdafx.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { WSADATA SData; int iResult = WSAStartup(0x0202,&SData); if (iResult!=0){ cout << "KHONG THE KHOI DONG WINSOCK"; return 1; } II. SOCKET 1. Socket là gì? “Socket là một cổng logic mà một chương trình sử dụng để kết nối với một chương trình khác chạy trên một máy tính khác trên Internet. Chương trình mạng có thể sử dụng nhiều Socket cùng một lúc, nhờ đó nhiều chương trình có thể sử dụng Internet cùng một lúc.” Ở đây ta hiểu Socket trong Winsock như là một “phương tiện” để ứng dụng mạng có thể trao đổi dữ liệu. Nghĩa là 1 Server thì sẽ cần một Socket để lắng nghe, chờ đợi các kết nối từ client và Client thì phải cần có một Socket để kết nối tới Sever. 2. Khởi tạo Socket Chúng ta sử dụng cấu trúc SOCKET để lưu giữ 1 Socket. Và có thể sử dụng hàm sau đây để tạo Socket. SOCKET socket ( int af, int type, int protocol ); Ví dụ: SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); Trong đó: * af: Là một con số ID để quyết định Socket của chúng ta sử dụng giao thức (protocol) để kết nối. - AF_INET : TCP/IP (Phổ biến nhất hiện nay -> dùng địa chỉ IP để truyền dữ liệu) - AF_NETBIOS: NetBIOS (Giao thức dùng tên máy để truyền dữ liệu) - AF_APPLETALK: AppleTalk - AF_ATM: ATM … Và ở trong Tut này mình chỉ nghiên cứu tới TCP/IP. * type: Quy định giao thức vận chuyển dữ liệu Ví dụ với giao thức TCP/IP thì có 2 giao thức cốt lõi là UDP và TCP: - SOCK_DGRAM: Hay là giao thức UDP. Khi chương trình chúng ta dùng UDP để truyền dữ liệu thì chuyện gì sẽ xảy ra giữa bên gởi và bên nhận? Bên gửi cứ gửi và gửi và nó không hề quan tâm tới vấn đề bên nhận có nhận được nó hay không? => Ưu điểm: Tốc độ truyền dữ liệu nhanh. => Nhược điểm: Khả năng sai, mất dữ liệu sẽ rất lớn. Vậy dùng UDP khi nào? Những ứng dụng cần dữ liệu tức thời như: - Chương trình nghe nhạc trực tuyến. Vấn đề sai bit (vấp khi nghe nhạc) không quan trọng mấy vì yêu cầu của nó là đảm bảo tốc độ nhanh. - Chương trình Chat chẳn hạn. - Hoặc GameOnline (thỉnh thoảng bạn bị trường hợp LAG chính là do bị mất dữ liệu trên đường truyền đó) - SOCK_STREAM: Đây là giao thức TCP. Nó ngược với UDP vì nó đảm bảo giữa bên gửi và bên nhận dữ liệu phải chính xác. Vì vậy 2 bên sẽ phải bắt tay rất nhiều lần khi truyền được dữ liệu (ví dụ như bên gửi sẽ gửi n gói tin (packet), bên nhận sẽ kiểm tra có bị mất hay sai gói tin nào hay không, nếu đủ thì nó sẽ yêu cầu bên gửi gửi tiếp n gói tin tiếp theo, ngược lại thì nó sẽ yêu cầu gửi lại) => Ưu điểm: Chất lượng gởi tin cậy. => Nhược điểm: Chậm hơn UDP. Những ứng dụng như WEB, MAIL, FTP,… - SOCK_RAW: Là giao thức để kiểm soát mạng, kiểm tra kết nối… Ví dụ: Start -> Run -> CMD: “ping diendantinhoc.com”. Nếu bạn nhận được Reply có nghĩa là giữa máy tính của bạn với máy chủ “diendantinhoc.com” có “thông mạng” với nhau. Và gói tin mà bạn PING chính là SOCK_RAW (ICMP Packet) * protocol: Chỉ định rõ lại giao thức mà thôi. Vì SOCK_RAW có 2 protocol là ICMP và RAW nên nó cần điều này - SOCK_DGREAM -> protocol là: IPPROTO_UDP - SOCK_STREAM -> protocol là: IPPROTO_IP - SOCK_RAW -> protocol có thể là: IPPROTO_RAW hay IPPROTO_ICMP Các bạn có thể tham khảo thêm bảng thể hiện các thuộc tính của hàm SOCKET: 3. Một số hàm lấy thông tin về mạng a. Lấy thông tin Socket int WSAEnumProtocols ( LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer, LPDWORD lpdwBufferLength ); lpiProtocols: NULL lpProtocolBuffer: Kiểu dữ liệu trả về lpdwBufferLength: Kích thước của kiểu dữ liệu Tuy nhiên việc sử dụng hàm này còn hơi rườm rà. Ví dụ: WSAEnumProtocols(NULL,NULL,&size); // -> Lấy kích thước kiểu dữ liệu WSAPROTOCOL_INFO *lpProtocolBuffer; lpProtocolBuffer = (WSAPROTOCOL_INFO*) malloc(size); WSAEnumProtocols(NULL, lpProtocolBuffer,&size); b. Lấy tên máy tính của mình int gethostname(char* name, int namelen); Ví dụ: char lpMyPCName[10]; gethostbyname(lpMyPCName,10) cout<< lpMyPCName; c. Làm việc với IP “Mình sẽ đi nhanh và giới thiệu sơ qua về phần này. Ở phần Địa Chỉ Mạng sắp tới mình sẽ nói rõ hơn IP”. Địa chỉ IP là 1 con số 4 byte để xác định 1 host trên mạng. Ví dụ: “192.168.11.1” [Byte1: 192] [Byte2: 168][ [Byte3: 11][ [Byte4: 1] Có thể biểu diễn địa chỉ IP: unsigned long (4 bytes) Hoặc một char* lpIP; Sử dụng inet_addr và inet_ntoa để chuyển đổi qua lại giữa u_long và char* u_long YahooAddr = inet_addr("216.109.112.135"); cout << "IP: " << inet_ntoa(*(in_addr*) &YahooAddr) << "\n"; d. Lấy IP theo tên máy struct hostent* FAR gethostbyname(const char* name); Trong đó typedef struct hostent { char FAR* h_name; // Tên máy tính char FAR FAR** h_aliases; // Bí danh máy tính short h_addrtype; // Kiểu IP (AF_INET) short h_length; // Kích thước IP char FAR FAR** h_addr_list; // Danh sách các địa chỉ IP // 1 host có thể có 1 hoặc nhiều IP } HOSTENT, Ví dụ như: char lpHostName[100]; hostent *MyPC; gethostname(lpHostName,100); MyPC = gethostbyname(lpHostName); e. Lấy tên máy theo địa chỉ IP Tương tự nhưng ngược lại. hostent* FAR gethostbyaddr(const char* addr, int len, int type); Ví dụ lấy thông tin Yahoo (có địa chỉ IP: 216.109.112.135) hostent *Yahoo; u_long YahooAddr = inet_addr("216.109.112.135"); Yahoo = gethostbyaddr((char*)&YahooAddr,4,AF_INET); Chương trình mẫu khởi tạo Socket: III. ĐỊA CHỈ MẠNG Thread trước mình đã giới thiệu về SOCKET tuy nhiên mình chỉ nói khởi tạo, còn việc để gửi hay nhận gói tin cần phải thêm thông tin về địa chỉ IP cho nó nữa. Ở Thread này mình sẽ tạm gác lại về SOCKET và C/C++ để đi sâu vào kiến thức cơ bản mạng cụ thể là địa chỉ IP. Bởi vì bạn muốn lập trình được chương trình truyền dữ liệu trên protocol TCP/IP mà không biết về IP thì hơi vô lý. Do đó cái thread này có phần đi ngoài lề về lập trình 1 xíu. 1. Địa chỉ IP Một HOST muốn giao dịch trên mạng sử dụng giao thức TCP/IP thì cần phải có 1 địa IP duy nhất để xác địch chính nó (như địa chỉ nhà bạn) trên môi trường mạng. Hiện nay có 2 loại địa chỉ IP. Đó là IPv4 (4 bytes) và IPv6. Tuy nhiên IPv6 vẫn chưa thể thay thế cho IPv4 được bởi vì số thiết bị dùng IPv4 quá nhiều. Cài đặt địa chỉ IP ở đâu ? Hiện này IPv4 sử dụng rất nhiều và nó sẽ dùng 4bytes (32bit) để biểu diễn 1 địa chỉ Cấu trúc địa chỉ bao gồm 2 phần là: Network_id và Host_id 2. Các lớp địa chỉ IP [...]... 192.168.11.0) Như vậy: - Network_id sẽ quy định host trong đó thuộc “đường mạng nào Và các host chỉ thấy nhau khi cùng “đường mạng - Host_id: dùng để phân biệt host với tất cả các host khác trong mạng Tiếp tục… Nếu để 2 đường mạng như trên 192.168.10.0 và 192.168.11.0 có thể “liên lạc” với nhau thì sao? Người ta cần định tuyến mạng với thiết bị mạng có tên là Router (Modem ADSL cũng là 1 router) hoặc một máy... giờ, các bạn lập trình với mục đích là tạo ra được một ứng dụng Nhưng ứng dụng đó chỉ hoạt động độc lập 1 mình riêng lẽ Mục tiêu lập trình mạng sẽ đưa ra những ứng dụng dạng Client – Server Tức là sẽ có 2 loại ứng dụng chính đó là Client và Server Quy trình hoạt động của ứng dụng Server – Client như sau: - Server có nhiệm vụ của là lắng nghe, chờ đợi kết nối từ Client trên địa chỉ IP của mình với PORT... động của giao thức TCP/IP và Internet" 6 Biểu diễn địa chỉ IP trong Winsock Quay lại về vấn đề WINSOCK Tại sao IP quan trọng trong lập trình mạng như vậy, bởi vì IP rất quan trọng trong mô hình TCP/IP - 1 Server phải có 1 IP để lắng nghe kết nối trên địa chỉ IP của mình - 1 Client muốn kết nối với Server thì phải có IP của Server… Trong Winsock người ta sử dụng cấu trúc sockaddr_in để biểu diễn địa chỉ... Proxy… => Router là một thiết bị có 2 card mạng và sẽ có ít nhất 2 địa chỉ IP Trong hình trên thì Card mạng thứ 2 của hai router phải thiết lập sao cho có cùng đường mạng để “liên lạc với nhau” Ví dụ như là 192.168.12.0 Như vậy LAN 1 sẽ liên lạc được với LAN 2 thông qua 2 router trên hình 3 Tại sao lại phân loại địa chỉ IP - Là do nhu cầu của từng môi trường mạng Ví dụ ở lớp A: - Network_id sẽ là 1... ta trích mỗi lớp một khoảng làm IP LAN và nó chỉ có tác dụng giao dịch trong mạng LAN Chúng ta có thể đặt IP cho card mạng với những khoảng dưới đây Lớp A: 10.0.0.0 đến 10.255.255.255 (số lượng đường mạng 1) Lớp B: 172.16.0.0 đến 172.31.255.255 (số lượng đường mạng 16) Lớp C: 192.168.0.0 đến 192.168.255.255 (số lượng đường mạng 256) b IP WAN (PUBLIC IP): Là các IP còn lại không thuộc IP LAN Đây là IP... Mask: 255.0.0.0 - Địa chỉ BroadCast (đại diện cho tất cả các máy trong đường mạng -> Khi gởi tới địa chỉ này thì mọi host trong mạng sẽ nhận) x x x.255.255.255 - Địa chỉ Network (đai diện bất kỳ một máy trong mạng – thư ng dùng để kiểm soát, định tuyến,…) x x x.0.0.0 Ví dụ: 10.1.1.1 * Trong lớp A có đường mạng 127.0.0.0 là đường mạng không sử dụng, nó được sử dụng để kiểm tra giao thúc TCP/IP Ví dụ bạn... bits): -> 2^16 – 2 = 65.534 (hosts) => Số đường mạng lớp B và số host vừa nhau Ví dụ ở lớp C: - Network_id sẽ là 3 bytes (24 bits) -> Nó sẽ có 2^23 = 2.097152 (đường mạng) - Host_id là (8 bits): -> 2^8 – 2 = 254 (Hosts) => Số đường mạng lớp C rất nhiều những host mỗi đường mạng lại rất ít Và có lẽ lớp C là lớp được sử dụng nhiều trong mạng LAN bởi lẽ với con số PC dưới 100 trên phòng máy thì lớp C... 127 (đường mạng) + Tại sao là 8 bit nhưng lại là 2^7 ? -> Là vì số bit từ làm Subnet là 0 -> 7 (biểu diễn tới 2^7) - Host_id là (24 bits): -> 2^24 – 2 = 16.777.214 (Hosts) (trừ 2 địa chỉ Broadcast và Subnet) => Ở lớp A số đường mạng ít nhưng số host trên đường mạng nhiều -> thích hợp với các công ty lớn Ví dụ ở lớp B: - Network_id sẽ là 2 bytes (16 bits) -> Nó sẽ có 2^15 = 16.384 (đường mạng) - Host_id... lại (trong 1 Network không được trùng) - Subnet Mask: 255.255.255.0 - Địa chỉ BroadCast (đại diện cho tất cả các máy trong đường mạng -> Khi gởi tới địa chỉ này thì mọi host trong mạng sẽ nhận) x x x.x x x.x x x.255 - Địa chỉ Network (đai diện bất kỳ một máy trong mạng – thư ng dùng để kiểm soát, định tuyến,…) x x x.x x x.x x x.0 Ví dụ: 192.168.23.3 d Network_id và Host_id có ý nghĩa gì? Ví dụ địa... còn lại (trong 1 Network không được trùng) - Subnet Mask: 255.255.0.0 - Địa chỉ BroadCast (đại diện cho tất cả các máy trong đường mạng -> Khi gởi tới địa chỉ này thì mọi host trong mạng sẽ nhận) x x x.x x x.255.255 - Địa chỉ Network (đai diện bất kỳ một máy trong mạng – thư ng dùng để kiểm soát, định tuyến,…) x x x.x x x.0.0 Ví dụ: 172.11.22.3 c Lớp C - Số byte làm Network_id: 3 byte (địa chỉ đầu tiên . [VC++] Lập Trình Mạng Với Thư Viện Winsock [VC++] Lập Trình Mạng Với Thư Viện Winsock I. KHỞI ĐỘNG WINSOCK Để lập trình được Winsock chúng ta sẽ khai báo thư viện winsock2 .h. là gì? Trước tới giờ, các bạn lập trình với mục đích là tạo ra được một ứng dụng. Nhưng ứng dụng đó chỉ hoạt động độc lập 1 mình riêng lẽ. Mục tiêu lập trình mạng sẽ đưa ra những ứng dụng. đó thuộc “đường mạng nào. Và các host chỉ thấy nhau khi cùng “đường mạng - Host_id: dùng để phân biệt host với tất cả các host khác trong mạng Tiếp tục… Nếu để 2 đường mạng như trên 192.168.10.0

Ngày đăng: 13/08/2014, 13:22

TỪ KHÓA LIÊN QUAN

w