Professional Documents
Culture Documents
Win Sock
Win Sock
Win Sock
I. KHi NG WINSOCK
lp trnh c Winsock chng ta s khai bo th vin winsock2.h (cha cc prototypes) v 1 file lib (chnh l file .cpp c bin dch thnh .lib) c tn l ws2_2.lib. By gi hy to 1 project Windows32 Console Project. Lu : Chng ta khng khai bo trong file .cpp c hm main m khai bo trong file stdafx.h. y l cch khai bo th vin ca Visual C++. #include <stdio.h> #include <tchar.h> #include <winsock2.h> #pragma comment (lib,ws2_32.lib) V by gi s l nhng hm khi to Winsock: int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData); Trong : - wVersionRequested l phin bn th vin m mnh s dng. y s l gi tr 00202 c ngha l phin bn 2.2. Chng ta c th dng macro MAKEWORD(2,2) tr v gi tr 00202. - lpWSData l mt s thng tin b sung s c tr v sau khi gi khi to Winsock.: typedef struct WSAData { WORD wVersion; // Phin bn hin ti WORD wHighVersion; // Phin bn c th h tr char szDescription[WSADESCRIPTION_LEN + 1]; // Ghi ch char szSystemStatus[WSASYS_STATUS_LEN + 1]; // Trng thi h thngunsigned short iMaxSockets; // Khng s dng t Version 2 tr i unsigned short iMaxUdpDg; // Khng s dng t Version 2 tr i char FAR * lpVendorInfo; // Khng s dng t Version 2 tr i } WSADATA, FAR * LPWSADATA; V cui cng l hm hy Winsock khi kt thc chng trnh. int WSACleanup (void);
Chng trnh u tin: #include stdafx.h using namespace std; int _tmain(int argc, _TCHAR* argv[]) { WSADATA SData; int iResult = WSAStartup(00202,&SData); 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; } II. SOCKET 1. Socket l g? Socket l mt cng logic m mt chng trnh s dng kt ni vi mt chng trnh khc chy trn mt my tnh khc trn Internet. Chng trnh mng c th s dng nhiu Socket cng mt lc, nh nhiu chng trnh c th s dng Internet cng mt lc. y ta hiu Socket trong Winsock nh l mt phng tin ng dng mng c th trao i d liu. Ngha l 1 Server th s cn mt Socket lng nghe, ch i cc kt ni t client v Client th phi cn c mt Socket kt ni ti Sever. 2. Khi to Socket Chng ta s dng cu trc SOCKET lu gi 1 Socket. V c th s dng hm sau y to Socket. SOCKET socket ( int af, int type, int protocol );
V d: SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); Trong : * af: L mt con s ID quyt nh Socket ca chng ta s dng giao thc (protocol) kt ni. - AF_INET : TCP/IP (Ph bin nht hin nay -> dng a ch IP truyn d liu) - AF_NETBIOS: NetBIOS (Giao thc dng tn my truyn d liu) - AF_APPLETALK: AppleTalk - AF_ATM: ATM V trong Tut ny mnh ch nghin cu ti TCP/IP. * type: Quy nh giao thc vn chuyn d liu. V d vi giao thc TCP/IP th c 2 giao thc ct li l UDP v TCP: - SOCK_DGRAM: Hay l giao thc UDP. Khi chng trnh chng ta dng UDP truyn d liu th chuyn g s xy ra gia bn gi v bn nhn? Bn gi c gi v gi v n khng h quan tm ti vn bn nhn c nhn c n hay khng? => u im: Tc truyn d liu nhanh. => Nhc im: Kh nng sai, mt d liu s rt ln. Vy dng UDP khi no? Nhng ng dng cn d liu tc thi nh: - Chng trnh nghe nhc trc tuyn. Vn sai bit (vp khi nghe nhc) khng quan trng my v yu cu ca n l m bo tc nhanh. - Chng trnh Chat chn hn. - Hoc GameOnline (thnh thong bn b trng hp LAG chnh l do b mt d liu trn ng truyn ) - SOCK_STREAM: y l giao thc TCP. N ngc vi UDP v n m bo gia bn gi v bn nhn d liu phi chnh xc. V vy 2 bn s phi bt tay rt nhiu ln khi truyn c d liu (v d nh bn gi s gi n gi tin (packet), bn nhn s kim tra c b mt hay sai gi tin no hay khng, nu th n s yu cu bn gi gi tip n gi tin tip theo, ngc li th n s yu cu gi li) => u im: Cht lng gi tin cy. => Nhc im: Chm hn UDP. Nhng ng dng nh WEB, MAIL, FTP, - SOCK_RAW: L giao thc kim sot mng, kim tra kt ni V d: Start -> Run -> CMD: ping congdongcviet.com. Nu bn nhn c Reply c ngha l gia my tnh ca bn vi my ch congdongcviet.com c thng mng vi nhau. V gi tin m bn PING chnh l SOCK_RAW (ICMP Packet)
3
* protocol: Ch nh r li giao thc m thi. V SOCK_RAW c 2 protocol l ICMP v RAW nn n cn iu ny. - SOCK_DGREAM -> protocol l: IPPROTO_UDP - SOCK_STREAM -> protocol l: IPPROTO_IP - SOCK_RAW -> protocol c th l: IPPROTO_RAW hay IPPROTO_ICMP Cc bn c th tham kho thm bng th hin cc thuc tnh ca hm SOCKET:
3. Mt s hm ly thng tin v mng a. Ly thng tin Socket int WSAEnumProtocols ( LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer, LPDWORD lpdwBufferLength ); lpiProtocols: NULL lpProtocolBuffer: Kiu d liu tr v. lpdwBufferLength: Kch thc ca kiu d liu. Tuy nhin vic s dng hm ny cn hi rm r. V d: WSAEnumProtocols(NULL,NULL,&size); // -> Ly kch thc kiu d liu WSAPROTOCOL_INFO *lpProtocolBuffer; lpProtocolBuffer = (WSAPROTOCOL_INFO*) malloc(size); WSAEnumProtocols(NULL, lpProtocolBuffer,&size); b. Ly tn my tnh ca mnh int gethostname(char* name, int namelen); V d: char lpMyPCName[10]; gethostbyname(lpMyPCName,10) cout<< lpMyPCName; c. Lm vic vi IP Mnh s i nhanh v gii thiu s qua v phn ny. phn a Ch Mng sp ti mnh s ni r hn IP. a ch IP l 1 con s 4 byte xc nh 1 host trn mng. V d: 192.168.11.1 [Byte1: 192] [Byte2: 168][ [Byte3: 11][ [Byte4: 1] C th biu din a ch IP: unsigned long (4 bytes) Hoc mt char* lpIP; S dng inet_addr v inet_ntoa chuyn i qua li gia u_long v char* u_long YahooAddr = inet_addr(216.109.112.135); cout << IP: << inet_ntoa(*(in_addr*) &YahooAddr) << \n; d. Ly IP theo tn my
5
struct hostent* FAR gethostbyname(const char* name); Trong : typedef struct hostent { char FAR* h_name; // Tn my tnh char FAR FAR** h_aliases; // B danh my tnh short h_addrtype; // Kiu IP (AF_INET) short h_length; // Kch thc IP char FAR FAR** h_addr_list; // Danh sch cc a ch IP // 1 host c th c 1 hoc nhiu IP } HOSTENT, V d nh: char lpHostName[100]; hostent *MyPC; gethostname(lpHostName,100); MyPC = gethostbyname(lpHostName); e. Ly tn my theo a ch IP Tng t nhng ngc li. hostent* FAR gethostbyaddr(const char* addr, int len, int type); V d ly thng 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);
III. Biu din a ch IP trong Winsock Quay li v vn WINSOCK Ti sao IP quan trng trong lp trnh mng nh vy, bi v IP rt quan trng trong m hnh TCP/IP. - 1 Server phi c 1 IP lng nghe kt ni trn a ch IP ca mnh. - 1 Client mun kt ni vi Server th phi c IP ca Server Trong Winsock ngi ta s dng cu trc sockaddr_in biu din a ch IP. struct sockaddr_in{ short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; Trong : - sin_family: AF_INET - sin_port: L port (cng logic) lng nghe kt ni. -> 1 ng dng Server hay Client rt cn 1 port lin lc trn mng. Bi v card mng s thng qua s hiu port ny nhn bit c gi tin ang nhn (hay gi i) ca ng dng no?
7
- Cc port di 1024 l nhng port dnh ring cho cc dch v nh: Mt s port nh: 80 (Web), 20,21 (FTP), Mail (25 SMTP, 993 POP3), 53 (DNS), 22 (SSH), 23 (Telnet) V d nh ta g http://www.google.com - http l giao thc WEB => Port 80. - www.google.com => IP: 72.14.207.99 Nh vy ti Client s khi to 1 port (ln hn 1024) kt ni ti a ch 72.14.207.99 qua port 80. Da vo s port ngi qun tr c th kim sot c mng v d nh ch c lt WEB (m port 80, 53) nhng chn ht cc port khc => Bn khng th chat v gameonline mc d c Internet. Vi s nguyn u_short (16bit) c ngha c th chn ti 2^16 = 65535 port s dng giao dch trn mng. ng dng ca chng ta phi chn port ln hn 1024 nu hng mun vit 1 Sever nh WEB hay FTP, - sin_addr: l mt struct xc nh a ch IP (c th l IP ca Server hoc IP ca chnh mnh,) - Nu sin_addr.s_addr = INADDR_ANY; Th IP s chnh l IP ca mnh. Cc Server thng dng chn a ch IP ca mnh v lng nghe kt ni.. - Nu sin_addr.s_addr = inet_addr(x x x.x x x.x x x.xx); Th IP s l IP ch nh theo chui. Client phi ch nh c IP ca Server mi k ni c. - sin_zero dnh 8 byte (khng s dng). V d: sockaddr_in ip; ip.sin_family = AF_INET; ip.sin_port = htons(99999); ip.sin_addr.s_addr = inet_addr(10.0.0.2); IV. NG DNG CLIENT SERVER 1. ng dng Client Server l g? Trc ti gi, cc bn lp trnh vi mc ch l to ra c mt ng dng. Nhng ng dng ch hot ng c lp 1 mnh ring l. Mc tiu lp trnh mng s a ra nhng ng dng dng Client Server. Tc l s c 2 loi ng dng chnh l Client v Server. Quy trnh hot ng ca ng dng Server Client nh sau: - Server c nhim v ca l lng nghe, ch i kt ni t Client trn a ch IP ca mnh vi PORT c quy nh sn. Khi client gi d liu ti Server th n phi gii quyt mt cng vic l nhn d liu -> x l -> tr kt qu li cho Client. - Client l ng dng c phc v, n ch gi truy vn v ch i kt qu t Server.
8
Trong m hnh TCP/IP c 2 giao thc l TCP v UDP v 2 giao thc ny s quyt nh cch thc hot ng ca Client Server nh th no? a. Hot ng ca Client Server trong giao thc TCP (SOCK_STREAM)
2. Mt s hm lin quan ti gi v nhn d liu a. BIND int bind( SOCKET s, const struct sockaddr FAR* name, int namelen );
10
Tc dng dng ca BIND l s gip cho SOCKET ca SERVER bit rng n s ch i kt ni v nhn d liu trn IP no v PORT bao nhiu? PORT nn chn y nn trong khong no: 0 -1023: L nhng PORT c s dng bi cc dch v nh WEB, FTP, - 1024-49151: L PORT dnh cho SERVER lng nghe. SERVER nn chn trong khong ny. 49152-65535: L PORT khi to ngu nhin dnh cho CLIENT kt ni ti Server. Hm Bind gm c 3 thng s: - SOCKET s: Socket c thit lp - sockaddr name: Cu trc ADDR bao gm a ch IP v PORT - int namelen: Kch thc ca cu trc sockaddr V d: #define MYPORT 12345// Chn giao thc TCP SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);// Thit lp IP sockaddr_in my_addr; my_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); my_addr.sin_addr.s_addr = INADDR_ANY; // a IP v PORT vo SOCKET bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)); b. LISTEN int listen( SOCKET s, int backlog ); K t khi gi hm ny th SERVER s bt u lng nghe kt ni ca mnh. Hm LISTEN gm c 2 thng s: - SOCKET s: Socket c thit lp IP v PORT. - int backlog: S kt ni cho php ch trong hng i khi Server cha chp nhn kt ni. (v i lc c th c ti 2 hay 3 client kt ni ti cng 1 lc). Gi tr tt nht l khong t 5 10. c. CONNECT int connect( SOCKET s, struct sockaddr *serv_addr, int addrlen );
11
Hm c gi t CLIENT nu n mun kt ni ti SERVER - SOCKET s: Socket c khi to. - sockaddr *serv_addr: IP v PORT ca Server. - int addrlen: Sizeof ca cu trc sockaddr. d. ACCEPT SOCKET accept( SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen ); Khi Client kt ni ti Server. N phi ch Server chp nhn kt ni (nu giao thc TCP) bng hm accept trn. Hm ACCEPT gm c 2 thng s: - SOCKET s: Socket lng nghe ca SERVER. - sockaddr addr: L cu trc sockaddr lu a ch IP v PORT ca CLIENT kt ni ti SERVER. - int addrlen: Kch thc cu trc a ch IP ny. Hm ACCPET tr v 1 SOCKET mi Socket mi c to ny i din cho 1 Connection (kt ni) mi gia Server v Client. Sau khi truyn d liu th ta phi ng SOCKET ny li bng hm close nh closesocket(connect); e. REVC/SEND * Nhn d liu trn giao thc TCP int recv( SOCKET s, char FAR* buf, int len, int flags ); * Gi d liu giao thc TCP int send( SOCKET s, const char FAR * buf, int len, int flags );
12
- SOCKET s: L SOCKET c to ra khi Server chp nhn kt ni t CLIENT - char FAR* buf: L d liu (dng BYTE char) nhn hay gi. - int len: Kch thc ca d liu. - int flags: Mt s c hiu i km (thng thng l 0). f. REVCFROM/SENDTO c s dng trn giao thc UDP int recvfrom( SOCKET s, char FAR* buf, int len, int flags, struct sockaddr *from, int *fromlen); Cc thng s: - SOCKET s: L SOCKET c to ra ban u. - char FAR* buf: L d liu (dng BYTE char) nhn - int len: Kch thc ca d liu nhn. - int flags: Mt s c hiu i km (thng thng l 0). - sockaddr *from: IP v PORT t bn gi. - int *fromlen: Sizeof cu trc addr. int sendto( SOCKET s,const char FAR *buf, int len,int flags, const struct sockaddr* to, int tolen ); - SOCKET s: L SOCKET c to ra ban u. - char FAR* buf: L d liu (dng BYTE char) gi - int len: Kch thc ca d liu gi. - int flags: Mt s c hiu i km (thng thng l 0). - sockaddr *to: IP v PORT ti bn nhn. - int tolen: Sizeof cu trc addr. g. CLOSE/SHUTDOWN int shutdown( SOCKET s, int how );
13
int closesocket (SOCKET s); Hy SOCKET sau mt kt ni hoc kt thc chng trnh. Tham s how ca shutdown: - SD_RECEIVE: ng SOCKET, khng cho php NHN nhng cho php GI. - SD_SEND: ng SOCKET, khng cho php GI nhng cho php NHN. - SD_BOTH: Khng cho GI v NHN (ging gi hm closesocket). Ti sao c chuyn ng nhng cho php gi v nhn, l do Winsock h tr rt nhiu giao thc nh ATM, IPX, do n c nhng ci phc tp, mnh cng khng hiu r bi v kh nng dch vn hn ch. V vy c l vn nn s dng SD_BOTH hoc closesocket). V. DEMO MINI WEBSERVER Tht ra y mnh khng c tham vng lm 1 Web Server thc s nh IIS hay Apache u? Mnh ch mun dng Winsock lm 1 chng trnh c th bin my tnh bn thnh 1 my ch Web. Ngha l c ai truy cp vo th n s tr li 1 Webpage. Trc ht mnh xin gii thiu giao thc HTTP. 1. Giao thc HTTP Bc 1: Gi s ngi s dng g a ch URL l: http://webserver.com/Page?ID=1 Lc ny th Client ti ngi s dng s Connect ti Webserver v gi mt ni dung Request nh sau:
GET /Page?ID=1 HTTP/1.1 Host: webserver.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/p ng,*/*;q=0.5 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
14
Keep-Alive: 300 Connection: keep-alive Ni dung trn bao gm: - GET (ly trang web). Ngoi ra cn c POST - Host: Tn SERVER mun kt ni! - User-Agent: Tn chng trnh Web Browser - Ngoi ra cn mt s thng tin v ngn ng. Nu khi nhn c trang WEB m trong Web cn c hnh nh hay m thanh th tip tc gi Request ti Server Nh: GET /samples/images/IMAGE.jpg HTTP/1.1 Bc 2: X l ti Server Lc ny ti Web Server s lm g? N s gi li 1 Header nh sau: HTTP/1.0 200 OK Server: <TN SERVER> Date: Content-Type: text/html Accept-Ranges: bytes Last-Modified: Content-Length: <kich thuoc trang WEB> V sau n s cn c vo yu cu ca Client: GET /Page?ID=1 HTTP/1.1 gi tr li 1 trang HTML hoc file hnh nh, m thanh tng ng. V d nh: <html> <head><title>DEMO WEBSERVER WINSOCKC++</title></head> <body> <h1>Hello eXecutve!</h1> <br> CopyRight 2007 by eXecutive; stairwaytoheaven187@yahoo.com </body> </html>
15
2. Chng trnh DEMO Nh vy . Chng ta s vit chng trnh. Hm Thit lp lng nghe trn PORT 80 #define MY_PORT 80 .. .. int SetupIPWS(SOCKET& ListenSock,sockaddr_in& MyListenIP) { MyListenIP.sin_family = AF_INET; MyListenIP.sin_port = htons( MY_PORT ); // PORT 80 MyListenIP.sin_addr.s_addr = INADDR_ANY; // IP ca mnh int nResult = bind(ListenSock, (sockaddr*) &MyListenIP,sizeof(MyListenIP)); // Gn IP PORT vo SOCKET if (nResult == -1){ cout << Loi khi thiet lap IP va PORT\n; WSAGetLastError(); ShutdownWS(ListenSock); return 1; } return 0; } Hm lng nghe phc v kt ni. void LoopListen(SOCKET& ListenSock,sockaddr_in& MyListenIP){ SOCKET NewConnection; sockaddr_in ConnectClient; int nSizeAddr; int nResult = listen(ListenSock,10); // Lng nghe kt ni if (nResult == -1){ cout << Khong the lang nghe ket noi\n; WSAGetLastError(); return; } cout << Dang lang nghe ket noi tai IP: << inet_ntoa(MyListenIP.sin_addr) << PORT: << MyListenIP.sin_port << \nCTRL + C de STOP SERVER\n\n; char lpBuffRevc[1024]={0}; // Ni dung nhn t CLIENT (REQUEST) // Ni dung gi tr li CLIENT char headers[] = HTTP/1.0 200 OK\r\n Server: eXecutive Winsock Server\r\n Date: Sat, 3 November 2007\r\n
16
Content-Type: text/html\r\n Accept-Ranges: bytes\r\n Content-Length: 187\r\n \r\n; // Kt thc Header \n char html[] = <html> <head><title>DEMO WEBSERVER WINSOCK C++ CopyRight eXecutive</title></head> \r\n <body>\r\n <h1>Hello eXecutve!</h1>\r\n <br>\r\n CopyRight 2007 by eXecutive<br> \r\n stairwaytoheaven187@yahoo.com\r\n </body>\r\n </html>\r\n\n; // Kt thc trang web bng \n\n while (1){ nSizeAddr = sizeof(sockaddr); // Quan trng! Xc nh kch thc sockaddr NewConnection = accept(ListenSock, (sockaddr*) &ConnectClient, &nSizeAddr); // Chp nhn 1 kt ni if (NewConnection == -1){ cout << Loi ket noi tu Client\n; continue; } cout << Nhan ket noi tu: << inet_ntoa(ConnectClient.sin_addr) << \n; cout << \nNoi dung nhan:\n\n; // Xa ni dung REQUEST trc v nhn REQUEST mi. memset(lpBuffRevc,0,sizeof(lpBuffRevc)); recv(NewConnection,lpBuffRevc, sizeof(lpBuffRevc) ,0); /* X L REQUEST => Y MNH 1 KHNG 1 WEBSERVER CHUYN NGHIP NN B QUA. */ // Gi HEADER ca SERVER v trang HTML send(NewConnection,headers,sizeof(headers),0); send(NewConnection,html,sizeof(html),0); cout << lpBuffRevc << \n; // ng kt ni! closesocket(NewConnection); } }
17
C l 1 chng trnh k cc. While(1) khng c iu kin kt thc. Nhng l cch hoat ng ca SERVER, 1 chng trnh c th chy quanh nm sut thng. Do nn khng c vn g? a ch m mnh g l http://localhost tc l a ch cc b = http://127.0.0.1= http://192.168.1.254 (nu my tnh ca mnh t IP ny)
18
VI. DEMO MINI WEB BROWSER Ln ny mnh s DEMO 1 Web Browser. Chng trnh nh sau: - Ngi dng nhp vo a ch Website - Kt ni v ly ni dung HTML v lu li thnh file RESPONSE.htm
1. Cc thao tc ti WEB BROWSER a. Nhn a ch Website v phn gii tn min thnh a ch IP. char lpDomain[100]; cout << \n\nNhap ten mien can truy cap: http://; cin.getline(lpDomain,100); hostent *ConnectPC=NULL; ConnectPC = gethostbyname(lpDomain); // Lay PC theo Tn Domain if (!ConnectPC){ cout << DNS khong the phan giai duoc ten mien nay \n; return 1; } ConnectIP.sin_family = AF_INET;
19
ConnectIP.sin_port = htons( MY_PORT ); ConnectIP.sin_addr.s_addr = (*(DWORD*)ConnectPC->h_addr_list[0]); // Lay IP cout << \nMay chu:; cout << ConnectPC->h_name << \n; cout << IP: << inet_ntoa(ConnectIP.sin_addr) << \n; b. Gi REQUEST ti my ch WEB V d ngi s dng nhp l http://www.google.com th phi c Request ti thiu my ch x l l: GET / HTTP/1.1 Host: google.com User-Agent: eXecutive DEMO Client -> Host: google.com rt quan trng v c nhiu WEB thu HOSTING v lc ny c nhiu WEBSITE cng trn 1 WEBSERVER. Do phi xc nh min truy cp // NOI DUNG REQUEST char *GetHTML = GET / HTTP/1.1\r\n; char HostRequest[100]; sprintf(HostRequest,Host: %s\r\n,lpDomain); char *UserAgent = User-Agent: eXecutive DEMO Client \r\n\n; // GUI REQUEST send(Sock,GetHTML,strlen(GetHTML),0); send(Sock,HostRequest,strlen(HostRequest),0); send(Sock,UserAgent,strlen(UserAgent),0); c. Nhn RESPONSE t my ch WEB Nhn HEADER t SERVER: Nguyn tc l chng ta s nhn tng BYTE . Khi thy k t \n\n c ngha l kt thc Header. char HeaderResponse; while(!done){ nByteRevc = recv(Sock,&HeaderResponse,1,0); if(nByteRevc<0) // Loi done=TRUE; switch(HeaderResponse) { case \r: break; case \n: // Neu gap \n\n hay \n\r\n thi ket thuc Header if (EndHeader == true){ done = TRUE; }
20
EndHeader=true; break; default: EndHeader=false; break; } cout << HeaderResponse; } Nhn BODY t SERVER: Chng ta s nhn tng lc 512 Bytes t SERVER cho n khi khng c SERVER hi m na (nByteRevc <= 0) on CODE nh sau: char HTMLResponse[513]={0}; do{ nByteRevc = recv(Sock,HTMLResponse,sizeof(HTMLResponse)-1,0); // c 512 Bytes // Loai bo 1 ky tu bi thua tu HEADER if (HTMLResponse[0] == 0) HTMLResponse[0] = ; if(nByteRevc < 0) // Ket thuc HTML break; HTMLResponse[nByteRevc] = 0; // Ngt chui nu RESPONSE nhn < 512 BYTES hoc cui cng in chui. cout << HTMLResponse; }while (nByteRevc > 0); R rng gia send v recv khng phi tun theo quy tc l gi ba nhiu bytes th phi nhn by nhiu bytes. V chng ta c th gi hay nhn nhiu ln, vn ny khng quan trng trong WINSOCK! VII. DEMO CLIENT SERVER VI GIAO THC UDP 1. UDP l g? - Tht ra mnh gii thiu v UDP phn to SOCKET ri nhng mnh ni li 1 xu cho nhanh. UDP l mt trong 2 giao thc chnh ca m hnh TCP/IP truyn ti d liu. CLIENT SERVER s dng UDP s khng bao gi quan tm n v d liu c chnh xc hay khng? Bn gi c gi v bn nhn c nhn, nhn khng c th mc k - Ngi ta s dng UDP trong nhng ng dng cn truyn d liu nhanh nh CHAT, GAME ONLINE, .
21
- V ln ny mnh s DEMO 1 b ng dng Client Server lin lc vi nhau mClient khng cn bit IP Server s dng c ch Multicast hay Broadcast 2. BROADCAST hay MULTICAST l g? a. Broadcast Chng ta bit IP chia thnh 3 lp l A,B,C. Trong cu trc a ch IP bao gm NET_ID v HOST_ID -> Cc host ch thy nhau (lin lc c) khi chng c cng NET_ID. -> Mun host lin lc khi khc NET_ID th cn phi c c ch nh tuyn (s dng thit b router, Server c cu hnh Routing ) => Nh vy trong 1 NET_ID phi c 1 a ch no i din cho tt c cc HOST ng mng v chnh l a ch Broadcast V d: Lp A: C cc IP sau : 10.0.0.100, 10.12.3.1 hay 10.252.252.252 -> Tt c u c chung 1 ng mng 10.0.0.0 -> V IP i in l IP Broadcast: 10.255.255.255. Ngha l khi c 1 gi tin UDP gi ti a ch ny th tt c cc host trn u nhn c b. Multicast - a ch Broadcast i din cho tt c cc Host nhng trn cng 1 ng mng. - a ch Multicast i din cho tt c cc HOST trn tt c cc ng mng khc nhau Hay chnh xc hn th a ch 255.255.255.255 chnh l a ch Multicast. Khi gi 1 gi tin UDP Packet ti a ch ny th tt c cc host c th lin lc c vi host gi (khc ng mng phi c c ch nh tuyn) u nhn c gi tin ny. Tuy nhin lu 1 iu l Multicast hay Broadcast ch c gi tr trong IPLAN 3. Chng trnh DEMO tng: Bn chi Game Counter Strike cha??? - R rng my Server trong mng LAN c th l bt c my tnh no m Gamer chn Create Game? => Vy lm sao Client c th bit c IP my ch Connect. V n phi s dng c ch tm IP SERVER s dng UDP Broadcast.
a. SERVER Cng nh TCP. Nhim v chnh ca n l lng nghe, tuy nhin ch khc chc nng l khng cn phi chp nhn kt ni t Client. // Thit lp IP PORT pAddr->sin_family = AF_INET; pAddr->sin_port = htons(MY_PORT); pAddr->sin_addr.S_un.S_addr = ADDR_ANY; // Tm a ch IP ca SERVER <sau ny tr li cho CLIENT> char lpName[100]; char lpMyIP[100]={0}; gethostname(lpName,sizeof(lpName)); hostent* pMyServer = gethostbyname(lpName); u_long myIP = *(u_long*)pMyServer->h_addr_list[0]; strcpy(lpMyIP,inet_ntoa(*(in_addr*)&myIP)); // // a thng tin IP v 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; }
23
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){ // Nhn kt ni 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; // Kim tra yu cu ca CLIENT if (strcmpi(IP may chu dau???,buff)==0){ cout << Hieu yeu cau tu Client!\n; // Gi tr li cho CLIENT a ch IP ca mnh 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 -> Nhim v chnh ca CLIENT l gi 1 gi tin BROADCAST vi PORT quy nh sn Trong chng trnh ca CLIENT c 1 hm rt quan trng cho php SOCKET gi ti a ch BROADCAST setsockopt(*sock,SOL_SOCKET,SO_BROADCAST,(char*)&b SockBroadcast,sizeof(BOOL)); - Op ty chn y l : SO_BROADCAST (gi gi tin Broadcast); - bSockBroadcast: TRUE (cho php), FALSE (khng cho php).
24
int FindServer(SOCKET* sock,sockaddr_in* pServerAddr){ BOOL bSockBroadcast=true; setsockopt(*sock,SOL_SOCKET,SO_BROADCAST,(char*)&bSockBroadcast,sizeof(B OOL)); 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 l MULTICAST int nSend; int nRevc; int nAddrLen; char buff[512]=IP may chu dau???; // Thng tin gi ti my ch // Gi ti my ch nSend = sendto(*sock,buff,sizeof(buff),0,(sockaddr*)pServerAddr,sizeof(sockaddr_in)); cout << Da gui << nSend << bytes\n; // Nhn hi m ca my 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; }
25