Win Sock

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 25

Lp trnh WINSOCK

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);

Chng trnh mu khi to Socket:

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)

b. Hot ng ca Client Server trong giao thc UDP (SOCK_DGRAM)

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.

V chng trnh DEMO ca mnh s nh sau:


22

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).

Hm ny c rt nhiu Option. Cc bn c th tham kho thm MSDN.

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

You might also like