“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[r]
(1)[VC++] Lập Trình Mạng
(2)[VC++] Lập Trình Mạng Với Thư Viện Winsock
I KHỞI ĐỘNG WINSOCK
Để lập trình Winsock khai báo thư viện winsock2.h (chứa prototypes) file lib (chính file cpp biên dịch thành lib) có tên ws2_2.lib
Bây tạo project Windows32 Console Project
Lưu ý: Chúng ta không khai báo file cpp có hàm main mà khai báo
file stdafx.h Đây cách khai báo thư viện Visual C++
#include <tchar.h>
#include <winsock2.h>
#pragma comment (lib,"ws2_32.lib")
Và hàm để khởi tạo Winsock:
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
Trong đó:
- wVersionRequested phiên thư viện mà sử dụng Ở giá trị 0x0202 có nghĩa phiên 2.2 Chúng ta dùng macro
MAKEWORD(2,2) để trả giá trị 0x0202
- lpWSData số thông tin bổ sung trả sau gọi khởi tạo
Winsock.:
typedef struct WSAData {
WORD wVersion; // Phiên
WORD wHighVersion; // Phiên hỗ trợ
char szDescription[WSADESCRIPTION_LEN + 1]; // Ghi
char szSystemStatus[WSASYS_STATUS_LEN + 1]; // Trạng thái hệ
thống
unsigned short iMaxSockets; // Không sử dụng từ Version trở
unsigned short iMaxUdpDg; // Không sử dụng từ Version trở
char FAR * lpVendorInfo; // Không sử dụng từ Version trở
} WSADATA, FAR * LPWSADATA;
Và cuối hàm hủy Winsock kết thúc chương trình nt WSACleanup (void);
(3)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 Socket gì?
“Socket cổng logic mà chương trình sử dụng để kết nối với chương trình khác chạy máy tính khác Internet Chương trình mạng sử dụng nhiều Socket lúc, nhờ nhiều chương trình sử dụng Internet lúc.”
Ở ta hiểu Socket Winsock “phương tiện” để ứng dụng
mạng trao đổi liệu Nghĩa Server cần Socket để lắng
nghe, chờ đợi kết nối từ client Client phải cần có 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ữ Socket Và sử dụng hàm sau để 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à số ID để định Socket sử dụng giao thức (protocol) để kết nối
(4)liệu)
- AF_NETBIOS: NetBIOS (Giao thức dùng tên máy để truyền liệu)
- AF_APPLETALK: AppleTalk - AF_ATM: ATM
…
Và Tut nghiên cứu tới TCP/IP * type: Quy định giao thức vận chuyển liệu
Ví dụ với giao thức TCP/IP có giao thức cốt lõi UDP TCP:
- SOCK_DGRAM: Hay giao thức UDP Khi chương trình dùng
UDP để truyền liệu chuyện xảy bên gởi bên nhận? Bên gửi gửi gửi khơng quan tâm tới vấn đề bên nhận có nhận
nó hay khơng?
=> Ưu điểm: Tốc độ truyền liệu nhanh
=> Nhược điểm: Khả sai, liệu lớn
Vậy dùng UDP nào? Những ứng dụng cần liệu tức thời như:
- Chương trình nghe nhạc trực tuyến Vấn đề sai bit (vấp nghe nhạc) khơng
quan trọng yêu cầu đả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 bị
dữ liệu đường truyền đó)
- SOCK_STREAM: Đây giao thức TCP Nó ngược với UDP đảm bảo
giữa bên gửi bên nhận liệu phải xác Vì bên phải bắt tay nhiều lần truyền liệu (ví dụ bên gửi gửi n gói tin
(packet), bên nhận kiểm tra có bị hay sai gói tin hay khơng, đủ
thì u cầu bên gửi gửi tiếp n gói tin tiếp theo, ngược lại 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 UDP
Những ứng dụng 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 Reply có nghĩa máy tính bạn với máy chủ
“diendantinhoc.com” có “thơng mạng” với Và gói tin mà bạn PING
(5)* protocol: Chỉ định rõ lại giao thức mà Vì SOCK_RAW có protocol ICMP RAW nên cần điều
- SOCK_DGREAM -> protocol là: IPPROTO_UDP - SOCK_STREAM -> protocol là: IPPROTO_IP
- SOCK_RAW -> protocol là: IPPROTO_RAW hay IPPROTO_ICMP Các bạn tham khảo thêm bảng thể thuộc tính hàm
(6)hostent* pMyServer = gethostbyname(lpName);
u_long myIP = *(u_long*)pMyServer->h_addr_list[0]; strcpy(lpMyIP,inet_ntoa(*(in_addr*)&myIP));
// - // Đưa thông tin IP PORT cho SOCKET
nResult = bind(*sock,(sockaddr*)pAddr,sizeof(sockaddr)); if (nResult == -1){
cout << "Loi thiet lap IP va PORT\n"; HuyWinsock(sock);
return 1; }
cout << "Dang lang nghe ket noi tren IP: " << lpMyIP << " port: " << MY_PORT << "\n\n";
int nAddrLen; int nRevc; int nSend;
sockaddr_in IPClient;
char buff[512]={0}; while (1){
// Nhận kết nối từ CLIENT
nAddrLen = sizeof(sockaddr_in); nRevc = recvfrom(*sock,buff,sizeof(buff),0, (sockaddr*)&IPClient,&nAddrLen);
buff[nRevc-1] = 0;
cout << "Nhan ket toi tu CLIENT IP: " << inet_ntoa(IPClient.sin_addr) << "\n";
cout << "Noi dung: \"" << buff << "\"\n"; // Kiểm tra yêu cầu CLIENT
(7)nSend =
sendto(*sock,lpMyIP,strlen(lpMyIP),0,(sockaddr*)&IPClient,sizeof(IPClient)) ;
cout << "Gui lai client: " << nSend << " Bytes\n"; }
else{
cout << "Khong hieu yeu cau tu Client!\n"; }
cout << "\n"; }
b CLIENT
-> Nhiệm vụ CLIENT gửi gói tin BROADCAST với PORT quy định sẵn
Trong chương trình CLIENT có hàm quan trọng phép
SOCKET gởi tới địa BROADCAST
setsockopt(*sock,SOL_SOCKET,SO_BROADCAST,(char*)&b SockBroadcast,sizeof(BOOL));
- Op tùy chọn : SO_BROADCAST (gởi gói tin Broadcast);
- bSockBroadcast: TRUE (cho phép), FALSE (không cho phép) Hàm có nhiều Option Các bạn tham khảo thêm MSDN int FindServer(SOCKET* sock,sockaddr_in* pServerAddr){ BOOL bSockBroadcast=true;
setsockopt(*sock,SOL_SOCKET,SO_BROADCAST,(char*)&bSockBroadcas t,sizeof(BOOL));
pServerAddr->sin_family = AF_INET;
pServerAddr->sin_port = htons(MY_PORT);
pServerAddr->sin_addr.S_un.S_addr = inet_addr("255.255.255.255"); // Địa
chỉ đích MULTICAST
(8)int nRevc;
int nAddrLen;
char buff[512]="IP may chu dau???"; // Thông tin gửi tới máy chủ
// Gửi tới máy chủ nSend =
sendto(*sock,buff,sizeof(buff),0,(sockaddr*)pServerAddr,sizeof(sockaddr_in)) ;
cout << "Da gui " << nSend << " bytes\n";
// Nhận hồi âm máy chủ
sockaddr_in ServerIP;
nAddrLen = sizeof(sockaddr_in);
nRevc = recvfrom(*sock,buff,sizeof(buff),0, (sockaddr*)&ServerIP, &nAddrLen);
buff[nRevc] = 0;
cout << "Da nhan " << nRevc << " bytes\n";
cout << "Noi dung nhan <IP SERVER>: " << buff << "\n"; return 0;
}
c Download Demo here Còn tiếp