![Linux編程-第8章-網(wǎng)絡編程課件_第1頁](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc1.gif)
![Linux編程-第8章-網(wǎng)絡編程課件_第2頁](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc2.gif)
![Linux編程-第8章-網(wǎng)絡編程課件_第3頁](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc3.gif)
![Linux編程-第8章-網(wǎng)絡編程課件_第4頁](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc4.gif)
![Linux編程-第8章-網(wǎng)絡編程課件_第5頁](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc5.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第8章網(wǎng)絡編程本章概述本章的學習目標主要內(nèi)容第8章網(wǎng)絡編程本章概述本章學習目標理解網(wǎng)絡通信結構和英特網(wǎng)連接,理解字節(jié)序、端口、套接字、IP地址、域名、客服端服務器模型等概念理解套接字地址結構,理解TCP網(wǎng)絡通信程序構架,掌握套接字接口函數(shù)調(diào)用規(guī)范讀懂網(wǎng)絡通信示例程序,掌握簡單網(wǎng)絡應用編程方法理解簡單HTML標記,理解URL,理解HTTP事務讀懂和理解簡單web服務器源代碼,理解其工作原理,并進行實驗驗證本章學習目標理解網(wǎng)絡通信結構和英特網(wǎng)連接,理解字節(jié)序、端口、本章主要內(nèi)容網(wǎng)絡通信結構套接字(socke)地址及設置網(wǎng)絡編程API接口網(wǎng)絡編程實例:toggleWEB編程基礎小型web服務器weblet本章主要內(nèi)容網(wǎng)絡通信結構8.1網(wǎng)絡通信結構Socket網(wǎng)絡通信與IPC機制IPC機制:消息隊列、共享內(nèi)存、IPC信號量
結構麻煩、不易使用、僅用于同機進程間通信
僅用于Linux/Unix環(huán)境Socket網(wǎng)絡通信:
標準、規(guī)范,基于TCP/IP協(xié)議
兩種模式:TCP通信(與管道類似)UDP通信(與消息隊列類似)
易于理解、使用,使用廣泛
既可用于單機進程間通信,也可用于不同計算機
進程間通信
8.1網(wǎng)絡通信結構Socket網(wǎng)絡通信與IPC機制2.客戶服務器模型
與網(wǎng)絡通信一般采取客戶服務器模型:2.客戶服務器模型3.網(wǎng)絡通信結構分層設計各層分工明確可靠性好,性能高3.網(wǎng)絡通信結構分層設計4.套接字編程模型結構:網(wǎng)卡、TCP協(xié)議、套接字(Socket)類比:網(wǎng)卡(單位門牌號)、TCP/IP協(xié)議(收發(fā)室)、套接字(信箱號)套接字:含有進程接收信息的完整地址(Socket地址:IP地址、端口號)4.套接字編程模型結構:網(wǎng)卡、TCP協(xié)議、套接字(Socke5.因特網(wǎng)連接(TCP連接)TCP連接:比喻連接通信雙方套接字的一條通信線路,
通信前建立,通信結束拆除一條TCP連接實際上就是一個文件描述符
可用read/write或send/recv進行數(shù)據(jù)收發(fā)地址:(cliaddr:cliport,servaddr:servport)5.因特網(wǎng)連接(TCP連接)TCP連接:比喻連接通信雙方套接6.因特網(wǎng)連接實例(網(wǎng)頁瀏覽)服務器端口號:規(guī)定為80客戶端端口號:隨機分配,123456.因特網(wǎng)連接實例(網(wǎng)頁瀏覽)服務器端口號:規(guī)定為808.2套接字地址設置1.套接字地址結構:structsockaddr早期定義:16字節(jié),適用于各種網(wǎng)絡環(huán)境structsockaddr{unsignedshortsa_family;/*protocolfamily*/charsa_data[14];}2.適合Internet環(huán)境的套接字地址結構/*Intenet-stylesocketaddressstructure*/structsockaddr_in{unsignedshortsa_family;/*協(xié)議族,網(wǎng)絡序*/unsignedshortsin_port;/*端口號,2字節(jié),網(wǎng)絡序*/
structin_addrsin_addr;/*IP地址,4字節(jié),網(wǎng)絡序
*/unsignedcharsin_zero[8];/*填充,8字節(jié)*/}structin_addr{unsignedints_addr;/*networkbyteorder(big-endian)*/};8.2套接字地址設置1.套接字地址結構:structs3.字節(jié)序(整數(shù)、浮點等)字符串:char*X=”ABCDEFGHIJ”‘A’‘B’‘C’‘J’…XX+1X+2X+9(1)問題的提出(主機序)整數(shù):unsignedintB[2]={0x12345678,0xabcdef};unsignedshortT=0x1234;void*A=(void*)B;unsignedint*K=(int*)malloc(sizeof(int));*K=0x12345678;AA+4&TK4142434A…XX+1X+2X+9即3.字節(jié)序(整數(shù)、浮點等)字符串:char*X=”ABC(2)大端模式、小端模式整數(shù):unsignedintB[2]={0x12345678,0xabcdef},T=1234;void*A=(void*)B;unsignedint*K=(int*)malloc(sizeof(int));*K=0x12345678;大端模式(Big-Endian:高位在低地址字節(jié),一般網(wǎng)絡序)AA+4&TK小端模式(Little-Endian:高位在低地址字節(jié),一般主機序):1234567800cdefab12D2345678AA+4&TK78563412efab00cd780456341204D2(2)大端模式、小端模式整數(shù):unsignedintB(3)主機序、網(wǎng)絡序轉(zhuǎn)換unsignedlonginthtonl(unsignedlonginthostlong);unsignedshortinthtons(unsignedshortinthostshort);返回:按照網(wǎng)絡字節(jié)順序的值。unsignedlongintntohl(unsignedlongintnetlong);unsignedshortintntohs(unsigedshortintnetshort);h:hostn:networkl:long,int,4字節(jié)s:short,2字節(jié)(3)主機序、網(wǎng)絡序轉(zhuǎn)換unsignedlongint練習題8.3閱讀下面代碼,假設主機采用小端模式,分析運行結果,并給出解釋:#include"wrapper.h"intmain(){ unsignedintm,n;unsignedshortk; char*a,*b,*c; m=0x12345678;n=htonl(0x12345678); a=(char*)&m;b=(char*)&n;c=(char*)&k;c[0]='1';c[1]='2'; printf("a[]=%2x%2x%2x%2x\n",a[0],a[1],a[2],a[3]); printf("b[]=%2x%2x%2x%2x\n",*b,*(b+1),*(b+2),*(b+3)); printf("k=%x\n",k);}練習題8.3閱讀下面代碼,假設主機采用小端模式,分析運行結4.IP地址32位整數(shù)(大端模式,網(wǎng)絡序):structin_addrIP1=htonl(0x8002c2f2);128=0x80,2=0x02,193=0xc2,242=0xf2點分十進制:42轉(zhuǎn)換函數(shù):intinet_aton(constchar*cp,structin_addr*inp);char*inet_ntoa(structin_addrin);a:字符串n:32位整數(shù)8002c2f24.IP地址32位整數(shù)(大端模式,網(wǎng)絡序):8002c2f練習題8.1完成下表:點分十進制地址十六進制地址
0x1
0xffffffff
0x7f000001
2
練習題8.1完成下表:點分十進制地址十六進制地址
0x1
5.因特網(wǎng)域名/*DNShostentrystructure,位于系統(tǒng)頭文件netdb.h*/structhostent{char*h_name;/*Officialdomainnameofhost*/char**h_aliases;/*Null-terminatedarrayofdomainname*/inth_addrtype;/*Hostaddresstype(AF_INET*/inth_length;/*Lengthofanaddress,inbytes*/char**h_addr_list;/*Null-terminatedarrayofin_addrstructs*/};5.因特網(wǎng)域名/*DNSh查詢域名和IP地址:(1)命令(1)API函數(shù)structhostent*gethostbyname(constchar*name);structhostent*gethostbyaddr(constchar*addr,intlen,0);查詢域名和IP地址:(1)命令(1)API函數(shù)structhostinfo.c#include"wrapper.h"intmain(intargc,char**argv){char**pp;structin_addraddr;structhostent*hostp;
if(argc!=2){…}
if(inet_aton(argv[1],&addr)!=0)hostp=Gethostbyaddr((constchar*)&addr,sizeof(addr),AF_INET);elsehostp=Gethostbyname(argv[1]);
printf("officialhostname:%s\n",hostp->h_name);for(pp=hostp->h_aliases;*pp!=NULL;pp++) printf("alias:%s\n",*pp);
for(pp=hostp->h_addr_list;*pp!=NULL;pp++){ addr.s_addr=*((unsignedint*)*pp); printf("address:%s\n",inet_ntoa(addr));}exit(0);}$./hostinfo31officialhostname:address:31$./hostinfoofficialhostname:address:address:28hostinfo.c#include"wrapper.h"8.3網(wǎng)絡通信API函數(shù)1、編程框架:8.3網(wǎng)絡通信API函數(shù)1、編程框架:2、網(wǎng)絡通信API函數(shù)(一)客戶端(1)創(chuàng)建套接字intsocket(intdomain,inttype,intprotocol);示例:client_sock=socket(AF_INET,SOCK_STREAM,0);(2)connect函數(shù)intconnect(intclient_sock,structsockaddr*serv_addr,intaddrlen);(3)包裝函數(shù)open_client_sock2、網(wǎng)絡通信API函數(shù)(一)客戶端intopen_client_sock(char*hostname,intport){intclient_sock;structhostent*hp;structsockaddr_inserveraddr;
if((client_sock=socket(AF_INET,SOCK_STREAM,0))<0) return-1;/*iferrorreturn-1*/
/*Fillintheserver'sIPaddressandport*/if((hp=gethostbyname(hostname))==NULL) return-2;/*iferrorreturn-2*/bzero((char*)&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;bcopy((char*)hp->h_addr_list[0], (char*)&serveraddr.sin_addr.s_addr,hp->h_length);serveraddr.sin_port=htons(port);
/*Establishaconnectionwiththeserver*/if(connect(client_sock,(SA*)&serveraddr,sizeof(serveraddr))<0) return-1;returnclient_sock;}intopen_client_sock(char*hos(二)服務器端intbind(intserv_sock,structsockaddr*my_addr,intaddrlen);intlisten(intserv_sock,intbacklog);
open_listen_sock包裝函數(shù):(二)服務器端intbind(intserv_sock,intopen_listen_sock(intport){intlisten_sock,optval=1;structsockaddr_inserveraddr;
/*Createasocketdescriptor*/if((listen_sock=socket(AF_INET,SOCK_STREAM,0))<0) return-1;
/*Eliminates"Addressalreadyinuse"errorfrombind*/if(setsockopt(listen_sock,SOL_SOCKET,SO_REUSEADDR, (constvoid*)&optval,sizeof(int))<0) return-1;
/*listen_sockisanendpointforallrequeststoportreceivedfromanyIPaddressforthishost*/bzero((char*)&serveraddr,sizeof(serveraddr));serveraddr.sin_family=AF_INET;serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);serveraddr.sin_port=htons((unsignedshort)port);if(bind(listen_sock,(SA*)&serveraddr,sizeof(serveraddr))<0) return-1;
/*convertthethesocktoalisteningsocketreadytoacceptconnectionrequests*/if(listen(listen_sock,LISTENQ)<0) return-1;returnlisten_sock;}intopen_listen_sock(intport)intaccept(intlisten_sock,structsockaddr*addr,int*addrlen);intaccept(intlisten_sock,st(三)數(shù)據(jù)收發(fā)(read/write、send/recv)ssize_tsend(intsock,constvoid*buff,size_tnbytes,intflags);
返回:若成功則為實際發(fā)送字節(jié)數(shù),若出錯則為SOCKET_ERROR.ssize_trecv(intsock,void*buff,size_tnbytes,intflags);
返回:若成功返回實際接收字節(jié)數(shù),若出錯則為SOCKET_ERROR,如果recv函數(shù)在等待協(xié)議接收數(shù)據(jù)時網(wǎng)絡中斷了,則返回0(三)數(shù)據(jù)收發(fā)(read/write、send/recv)s8.4網(wǎng)絡編程實例:toggle應用功能描述:客戶端togglec.c將從標準輸入讀到的字符串發(fā)送給服務端togglei.c,服務端將收到的字符串進行中的英文字母小寫轉(zhuǎn)大寫、大寫轉(zhuǎn)小寫后發(fā)給客戶端顯示出來。8.4網(wǎng)絡編程實例:toggle應用功能描述:客戶端tog#include"wrapper.h"intmain(intargc,char**argv){intclient_sock,port;char*host,buf[MAXLINE];rio_trio;if(argc!=3){ …}host=argv[1];port=atoi(argv[2]);client_sock=open_client_sock(host,port);while(fgets(buf,MAXLINE,stdin)!=NULL){ send(client_sock,buf,strlen(buf),0); recv(client_sock,buf,MAXLINE,0); fputs(buf,stdout);}close(client_sock);exit(0);}(1)客戶端togglec.c#include"wrapper.h"(1)客戶端toggintmain(intargc,char**argv){intlisten_sock,conn_sock,port,clientlen;structsockaddr_inclientaddr;structhostent*hp;char*haddrp;if(argc!=2){ 。。。}port=atoi(argv[1]);listen_sock=Open_listen_sock(port);while(1){clientlen=sizeof(clientaddr); conn_sock=accept(listen_sock,(SA*)&clientaddr,&clientlen); /*determinethedomainnameandIPaddressoftheclient*/ hp=Gethostbyaddr((constchar*)&clientaddr.sin_addr.s_addr, sizeof(clientaddr.sin_addr.s_addr),AF_INET); haddrp=inet_ntoa(clientaddr.sin_addr); printf("serverconnectedto%s(%s)\n",hp->h_name,haddrp); toggle(conn_sock); close(conn_sock);}exit(0);}服務器端togglesi.cintmain(intargc,char**argvvoidtoggle(intconn_sock){size_tn;inti;charbuf[MAXLINE];
while((n=recv(conn_sock,buf,MAXLINE,0))>0){ printf("toggleserverreceived%dbytes\n",n);
for(i=0;i<n;i++)if(isupper(buf[i])buf[i]=tolower(buf[i]);elseif(islower(buf[i]))buf[i]=toupper(buf[i]);
send(conn_sock,buf,n,0);}}toggle.cvoidtoggle(intconn_sock)tog編譯、運行$gcc-otogglectogglec.c-L.-lwrapper$gcc-otogglesitogglesi.ctoggle.c-L.-lwrapper編譯、運行$gcc-otogglectogg練習題8.4編寫一個網(wǎng)絡通信程序,客戶端從服務器端取指定文件保存,并顯示輸出。練習題8.5編寫一個網(wǎng)絡通信程序,客戶端將指定文件上傳到服務器端,服務器保存和輸出文件內(nèi)容。*練習題8.6查閱資料,采用UDP協(xié)議實現(xiàn)toggle客戶端和服務器。練習題8.4編寫一個網(wǎng)絡通信程序,客戶端從服務器端取指8.5Web編程基礎0.為何要用web編程前述網(wǎng)絡編程方法:客戶與服務器間傳送數(shù)據(jù)的含義由雙方預先約定應用升級要重新修改和部署服務器與客戶端一般客戶端分發(fā)和升級比較麻煩Web編程優(yōu)點:只需開發(fā)服務器端,客戶端為瀏覽器如果升級只需直接升級服務器端服務器端與客戶端之間有規(guī)范的通信協(xié)議8.5Web編程基礎0.為何要用web編程1.Web基礎(1)數(shù)據(jù)傳遞方法一般文本數(shù)據(jù)用超文本交互語言(html)文件傳遞。hello.html:<html><head><title>asimplepagefortestingweblet</title><head><body>Hello,<ahref=>dgut</a></body></html>顯示輸出:1.Web基礎(1)數(shù)據(jù)傳遞方法hello.html:顯示也可傳遞其他類型信息:常用MIME類型MIME類型描述text/htmltext/plainapplication/pdfimage/gifimage/jpeggzapplication/x-gzipvideo/mpeg.text/xmlhtml頁面無格式文本(如.txt文件)pdf文檔gif格式編碼的二進制圖像jpeg格式編碼的二進制圖像GZIP文件:
.gzMPEG文件:mpg,.mpegxml文件:.xml也可傳遞其他類型信息:常用MIME類型MIME類型描述tex(2)web(一般指服務器)提供Web內(nèi)容的過程:A.靜態(tài)網(wǎng)頁http://:80/index.html協(xié)議服務器地址服務器端口號缺省為80資源路徑和文件名,缺省為/index.html含義:用http協(xié)議請求服務器上web網(wǎng)站目錄/下index.html文件B.動態(tài)網(wǎng)頁http://:8000/cgi-bin/add?2017&523808協(xié)議服務器地址服務器端口號資源路徑和文件名參數(shù)含義:運行上web網(wǎng)站目錄/cgi-bin下的add程序,命令行參數(shù)為2017和523808,由該程序產(chǎn)生html格式內(nèi)容,發(fā)送給瀏覽器(2)web(一般指服務器)提供Web內(nèi)容的過程:協(xié)議服務器(3)HTTP事務http協(xié)議:在傳輸網(wǎng)頁內(nèi)容之前,先需在瀏覽器和WEB服務器間進行多次數(shù)據(jù)交換,達成某種共識,但用戶看不見整個傳輸過程為http事務可用telnet驗證,以訪問百度網(wǎng)站為例(3)HTTP事務http協(xié)議:1$telent80Client:請求連接百度web服務器2Trying12...telnet打印三行信息3Connectedto.4Escapecharacteris'^]'.5GET/HTTP/1.1Client:基于http1.1協(xié)議用GET方法請求網(wǎng)頁/index.html6HOST:WWW.BAIDU.COMClient:給出主機域名地址,這些都不顯示7Client:請求行用回車空行表示結束HTTP/1.1200OKServer:服務器響應行,200
OK表示無誤Date:Sun,06Aug201704:05:08GMTServer:幾個響應頭:時間、Content-Type:text/html類型:text/html
Content-Length:14613
返回文件index.html長度12Last-Modified:Thu,27Jul201704:30:00GMT最后修改時間13…14Accept-Ranges:bytes15Server:響應頭用空行結尾16<html>Server:響應體(index.html)開始17<head>18…19</body></html>Server:lastlineinresponsebody20Connectionclosedbyforeignhost.Server:關閉連接提示21$Clinet:closeconnectionandterminates1$telent80七、小型Web服務器:weblet.c1.主函數(shù)main建立tcp連接intmain(intargc,char**argv){intlisten_sock,conn_sock,port,clientlen;structsockaddr_inclientaddr;
/*Checkcommandlineargs*/if(argc!=2){。。。}port=atoi(argv[1]);
listen_sock=open_listen_sock(port);while(1){ clientlen=sizeof(clientaddr);
conn_sock=accept(listen_sock,(SA*)&clientaddr,&clientlen);
process_trans(conn_sock);/*processHTTPtransaction*/ close(conn_sock);}}七、小型Web服務器:weblet.c1.主函數(shù)main2.處理http事務(process_trans函數(shù))(1)處理請求行voidprocess_trans(intfd)//fd為網(wǎng)絡連接{intstatic_flag;structstatsbuf;charbuf[MAXLINE],method[MAXLINE],uri[MAXLINE],version[MAXLINE];charfilename[MAXLINE],cgiargs[MAXLINE];rio_trio;
/*readrequestlineandheaders*/rio_readinitb(&rio,fd);rio_readlineb(&rio,buf,MAXLINE);sscanf(buf,"%s%s%s",method,uri,version);if(strcasecmp(method,"GET")){error_request(fd,method,"501","NotImplemented","webletdoesnotimplementthismethod");return;}read_requesthdrs(&rio);以前例為例:3個請求行提取各元素:method=GET,uri=/version=http/1.1讀第一個請求行:GET/http/1.1處理其他請求頭:HOST:…
空行2.處理http事務(process_trans函數(shù))(1)(2)如何處理其他請求頭(read_requesthdrs函數(shù))voidread_requesthdrs(rio_t*rp){charbuf[MAXLINE];
rio_readlineb(rp,buf,MAXLINE);
while(strcmp(buf,“\r\n”)){//如果不是空行”\r\n” printf(“%s”,buf);//則輸出顯示之
rio_readlineb(rp,buf,MAXLINE);//否則結束循環(huán)
}return;}(2)如何處理其他請求頭(read_requesthdrs函(3)判斷靜態(tài)/動態(tài)網(wǎng)頁(process_trans函數(shù))static_flag=is_static(uri);//解析資源路徑if(static_flag)parse_static_uri(uri,filename);elseparse_dynamic_uri(uri,filename,cgiargs);intis_static(char*uri){if(!strstr(uri,"cgi-bin"))return1;elsereturn0;}判斷是否為靜態(tài)網(wǎng)頁請求行為:80/index.html時,uri=/index.html請求行為:8000/cgi-bin/add?2017&523808時,uri=/cgi-bin/add?2017&523808(3)判斷靜態(tài)/動態(tài)網(wǎng)頁(process_trans函數(shù))(4)uri路徑處理,得到文件路徑filename處理靜態(tài)網(wǎng)頁路徑(parse_static_uri函數(shù)):voidparse_static_uri(char*uri,char*filename){char*ptr;strcpy(filename,".");strcat(filename,uri);if(uri[strlen(uri)-1]=='/')strcat(filename,"home.html");}若uri=/index.html,則filename=./index.html若uri=/,則filename=./home.htiml(4)uri路徑處理,得到文件路徑filename處理靜態(tài)網(wǎng)處理動態(tài)網(wǎng)頁路徑(parse_dynamic_uri函數(shù)):
voidparse_dynamic_uri(char*uri,char*filename,char*cgiargs){char*ptr;ptr=index(uri,'?'); if(ptr){ strcpy(cgiargs,ptr+1); *ptr='\0'; } else strcpy(cgiargs,""); strcpy(filename,"."); strcat(filename,uri);}動態(tài)路徑的uri中必有?字符,以uri=/cgi-bin/add?2017&523808為例:執(zhí)行該函數(shù)后,cgiargs=“2017%523808”filename=./cgi-bin/add處理動態(tài)網(wǎng)頁路徑(parse_dynamic_uri函數(shù)):(5)錯誤檢測和分流處理if(stat(filename,&sbuf)<0){//判斷文件是否存在 error_request(fd,filename,"404","Notfound", "webletcouldnotfindthisfile"); return;}
if(static_flag){/*feedstaticcontent*/ if(!(S_ISREG(sbuf.st_mode))||!(S_IRUSR&sbuf.st_mode)){ error_request(fd,filename,"403","Forbidden", "webletisnotpermttedtoreadthefile"); return; }
feed_static(fd,filename,sbuf.st_size);}else{/*feeddynamiccontent*/ if(!(S_ISREG(sbuf.st_mode))||!(S_IXUSR&sbuf.st_mode)){ error_request(fd,filename,"403","Forbidden", "webletcouldnotruntheCGIprogram"); return; }
feed_dynamic(fd,filename,cgiargs);}}(5)錯誤檢測和分流處理if(stat(filename(6)如何返回靜態(tài)網(wǎng)頁(feed_static函數(shù))voidfeed_static(intfd,char*filename,intfilesize){intsrcfd;char*srcp,filetype[MAXLINE],buf[MAXBUF];
/*Sendresponseheaderstoclient*/get_filetype(filename,filetype);sprintf(buf,"HTTP/1.0200OK\r\n");sprintf(buf,"%sServer:webletWebServer\r\n",buf);sprintf(buf,"%sContent-length:%d\r\n",buf,filesize);sprintf(buf,"%sContent-type:%s\r\n\r\n",buf,filetype);rio_writen(fd,buf,strlen(buf));
/*Sendresponsebodytoclient*/srcfd=open(filename,O_RDONLY,0);srcp=mmap(0,filesize,PROT_READ,MAP_PRIVATE,srcfd,0);close(srcfd);rio_writen(fd,srcp,filesize);munmap(srcp,filesize);}voidget_filetype(char*filename,char*filetype){if(strstr(filename,".html")) strcpy(filetype,"text/html");elseif(strstr(filename,".jpg")) strcpy(filetype,"image/jpeg");elseif(strstr(filename,".mpeg"))strcpy(filename,"video/mpeg");elsestrcpy(filetype,"text/html");}(6)如何返回靜態(tài)網(wǎng)頁(feed_static函數(shù))void(7)靜態(tài)網(wǎng)頁功能測試A.準備測試網(wǎng)頁test.html,置于與weblet所在目錄:<html><head><title>asimplepagefortestingweblet</title><head><body>HelloWorld</body></html>B.編譯和運行weblet$gcc-owebletweblet.c-L.-lwrapper$./weblet12345C.用瀏覽器測試(7)靜態(tài)網(wǎng)頁功能測試A.準備測試網(wǎng)頁test.html,置D.用telnet命令測試$telnetlocalhost12345Trying::1...Trying...Connectedtolocalhost.Escapecharacteris'^]'.GET/test.htmlHTTP/1.0
HTTP/1.0200OKServer:webletWebServerContent-length:94Content-type:text/html
<html><head><title>asimplepagefortestingweblet</title><head><body>HelloWorld</body></html>Connectionclosedbyforeignhost.輸入不顯示D.用telnet命令測試$telnetlocalho練習題8.9閱讀圖8-18源代碼,修改第8、10、11、12行代碼,將狀態(tài)碼、文件大小、文件類型、寫入fd的buf長度與實際不同,通過瀏覽器和telnet,請求網(wǎng)頁test.html,觀察服務器響應和瀏覽器顯示結果,并給出解釋。練習題8.9閱讀圖8-18源代碼,修改第8、10、11、1(7)如何返回動態(tài)網(wǎng)頁(feed_dynamic函數(shù))voidfeed_dynamic(intfd,char*filename,char*cgiargs){charbuf[MAXLINE],*emptylist[]={NULL};intpfd[2];
/*ReturnfirstpartofHTTPresponse*/sprintf(buf,"HTTP/1.0200OK\r\n");rio_writen(fd,buf,strlen(buf));sprintf(buf,"Server:webletWebServer\r\n");rio_writen(fd,buf,strlen(buf));pipe(pfd);if(fork()==0){ close(pfd[1]);dup2(pfd[0],STDIN_FILENO);
dup2(fd,STDOUT_FILENO);/*fd為網(wǎng)絡連接*/ execve(filename,emptylist,environ);/*加載運行CGI程序/cgi-bin/add*/}close(pfd[0]);write(pfd[1],cgiargs,strlen(cgiargs)+1);//通過管道把參數(shù)傳遞給CGI程序wait(NULL);/*Parentwaitsforandreapschild*/close(pfd[1]);}(7)如何返回動態(tài)網(wǎng)頁(feed_dynamic函數(shù))voi(7)cgi程序addintmain(void){char*buf,*p;charcontent[MAXLINE];intn1=0,n2=0;
/*Extractthetwoargumentsfromstandardinput*/scanf("%d&%d",&n1,&n2);/*Maketheresponsebody*/sprintf(content,"Welcometoaddserver:");sprintf(content,"%sTHEInternetadder\r\n<p>",content);sprintf(content,"%sTheansweris:%d+%d=%d\r\n<p>", content,n1,n2,n1+n2);sprintf(content,"%sThanksforvisiting!\r\n",content);
/*GeneratetheHTTPresponse*/printf("Content-length:%d\r\n",strlen(content));printf("Content-type:text/html\r\n\r\n");printf("%s",content);fflush(stdout);exit(0);}cgi參數(shù)為:2017%523808產(chǎn)生text/html內(nèi)容(7)cgi程序addintmain(void){(8)動態(tài)網(wǎng)頁測試A.編譯和執(zhí)行服務器:$gcc-owebletweblet.c-L.-lwrapper$gcc-oaddadd.c$mkdircgi-bin$cpaddcgi-bin$
./weblet12345B.用瀏覽器測試(8)動態(tài)網(wǎng)頁測試A.編譯和執(zhí)行服務器:C.用telnet測試$
telnetlocalhost12345Trying::1...Trying...Connectedtolocalhost.Escapecharacteris'^]'.GET/cgi-bin/add?2017&523808HTTP/1.0
HTTP/1.0200OKServer:webletWebServerContent-length:115Content-type:text/html
Welcometo:THEInternetadditionportal.<p>Theansweris:2017+523808=523825<p>Thanksforvisiting!Connectionclosedbyforeignhost.C.用telnet測試$telnetlocalhost練習題8.10用shell或python實現(xiàn)CGI程序add,并調(diào)試之。練習題8.11編寫和運行CGI程序,在瀏覽器中顯示指定ls命令的內(nèi)容;編寫CGI程序,能通過瀏覽器輸入Linux命令,在瀏覽器顯示命令輸出。*練習題8.12輸入命令“./weblet12345”啟動weblet,用一個telnet進程來連接weblet,并輸入網(wǎng)頁瀏覽請求,在該請求處理未完成前,在瀏覽器地址欄輸入http://localhost:12345/test.html,將看到什么結果,并予以解釋*8.21修改toggle服務器代碼,使之每次向客戶端回送文本行,后接當前系統(tǒng)時間。練習題8.10用shell或python實現(xiàn)CGI程序aTheEndTheEnd第8章網(wǎng)絡編程本章概述本章的學習目標主要內(nèi)容第8章網(wǎng)絡編程本章概述本章學習目標理解網(wǎng)絡通信結構和英特網(wǎng)連接,理解字節(jié)序、端口、套接字、IP地址、域名、客服端服務器模型等概念理解套接字地址結構,理解TCP網(wǎng)絡通信程序構架,掌握套接字接口函數(shù)調(diào)用規(guī)范讀懂網(wǎng)絡通信示例程序,掌握簡單網(wǎng)絡應用編程方法理解簡單HTML標記,理解URL,理解HTTP事務讀懂和理解簡單web服務器源代碼,理解其工作原理,并進行實驗驗證本章學習目標理解網(wǎng)絡通信結構和英特網(wǎng)連接,理解字節(jié)序、端口、本章主要內(nèi)容網(wǎng)絡通信結構套接字(socke)地址及設置網(wǎng)絡編程API接口網(wǎng)絡編程實例:toggleWEB編程基礎小型web服務器weblet本章主要內(nèi)容網(wǎng)絡通信結構8.1網(wǎng)絡通信結構Socket網(wǎng)絡通信與IPC機制IPC機制:消息隊列、共享內(nèi)存、IPC信號量
結構麻煩、不易使用、僅用于同機進程間通信
僅用于Linux/Unix環(huán)境Socket網(wǎng)絡通信:
標準、規(guī)范,基于TCP/IP協(xié)議
兩種模式:TCP通信(與管道類似)UDP通信(與消息隊列類似)
易于理解、使用,使用廣泛
既可用于單機進程間通信,也可用于不同計算機
進程間通信
8.1網(wǎng)絡通信結構Socket網(wǎng)絡通信與IPC機制2.客戶服務器模型
與網(wǎng)絡通信一般采取客戶服務器模型:2.客戶服務器模型3.網(wǎng)絡通信結構分層設計各層分工明確可靠性好,性能高3.網(wǎng)絡通信結構分層設計4.套接字編程模型結構:網(wǎng)卡、TCP協(xié)議、套接字(Socket)類比:網(wǎng)卡(單位門牌號)、TCP/IP協(xié)議(收發(fā)室)、套接字(信箱號)套接字:含有進程接收信息的完整地址(Socket地址:IP地址、端口號)4.套接字編程模型結構:網(wǎng)卡、TCP協(xié)議、套接字(Socke5.因特網(wǎng)連接(TCP連接)TCP連接:比喻連接通信雙方套接字的一條通信線路,
通信前建立,通信結束拆除一條TCP連接實際上就是一個文件描述符
可用read/write或send/recv進行數(shù)據(jù)收發(fā)地址:(cliaddr:cliport,servaddr:servport)5.因特網(wǎng)連接(TCP連接)TCP連接:比喻連接通信雙方套接6.因特網(wǎng)連接實例(網(wǎng)頁瀏覽)服務器端口號:規(guī)定為80客戶端端口號:隨機分配,123456.因特網(wǎng)連接實例(網(wǎng)頁瀏覽)服務器端口號:規(guī)定為808.2套接字地址設置1.套接字地址結構:structsockaddr早期定義:16字節(jié),適用于各種網(wǎng)絡環(huán)境structsockaddr{unsignedshortsa_family;/*protocolfamily*/charsa_data[14];}2.適合Internet環(huán)境的套接字地址結構/*Intenet-stylesocketaddressstructure*/structsockaddr_in{unsignedshortsa_family;/*協(xié)議族,網(wǎng)絡序*/unsignedshortsin_port;/*端口號,2字節(jié),網(wǎng)絡序*/
structin_addrsin_addr;/*IP地址,4字節(jié),網(wǎng)絡序
*/unsignedcharsin_zero[8];/*填充,8字節(jié)*/}structin_addr{unsignedints_addr;/*networkbyteorder(big-endian)*/};8.2套接字地址設置1.套接字地址結構:structs3.字節(jié)序(整數(shù)、浮點等)字符串:char*X=”ABCDEFGHIJ”‘A’‘B’‘C’‘J’…XX+1X+2X+9(1)問題的提出(主機序)整數(shù):unsignedintB[2]={0x12345678,0xabcdef};unsignedshortT=0x1234;void*A=(void*)B;unsignedint*K=(int*)malloc(sizeof(int));*K=0x12345678;AA+4&TK4142434A…XX+1X+2X+9即3.字節(jié)序(整數(shù)、浮點等)字符串:char*X=”ABC(2)大端模式、小端模式整數(shù):unsignedintB[2]={0x12345678,0xabcdef},T=1234;void*A=(void*)B;unsignedint*K=(int*)malloc(sizeof(int));*K=0x12345678;大端模式(Big-Endian:高位在低地址字節(jié),一般網(wǎng)絡序)AA+4&TK小端模式(Little-Endian:高位在低地址字節(jié),一般主機序):1234567800cdefab12D2345678AA+4&TK78563412efab00cd780456341204D2(2)大端模式、小端模式整數(shù):unsignedintB(3)主機序、網(wǎng)絡序轉(zhuǎn)換unsignedlonginthtonl(unsignedlonginthostlong);unsignedshortinthtons(unsignedshortinthostshort);返回:按照網(wǎng)絡字節(jié)順序的值。unsignedlongintntohl(unsignedlongintnetlong);unsignedshortintntohs(unsigedshortintnetshort);h:hostn:networkl:long,int,4字節(jié)s:short,2字節(jié)(3)主機序、網(wǎng)絡序轉(zhuǎn)換unsignedlongint練習題8.3閱讀下面代碼,假設主機采用小端模式,分析運行結果,并給出解釋:#include"wrapper.h"intmain(){ unsignedintm,n;unsignedshortk; char*a,*b,*c; m=0x12345678;n=htonl(0x12345678); a=(char*)&m;b=(char*)&n;c=(char*)&k;c[0]='1';c[1]='2'; printf("a[]=%2x%2x%2x%2x\n",a[0],a[1],a[2],a[3]); printf("b[]=%2x%2x%2x%2x\n",*b,*(b+1),*(b+2),*(b+3)); printf("k=%x\n",k);}練習題8.3閱讀下面代碼,假設主機采用小端模式,分析運行結4.IP地址32位整數(shù)(大端模式,網(wǎng)絡序):structin_addrIP1=htonl(0x8002c2f2);128=0x80,2=0x02,193=0xc2,242=0xf2點分十進制:42轉(zhuǎn)換函數(shù):intinet_aton(constchar*cp,structin_addr*inp);char*inet_ntoa(structin_addrin);a:字符串n:32位整數(shù)8002c2f24.IP地址32位整數(shù)(大端模式,網(wǎng)絡序):8002c2f練習題8.1完成下表:點分十進制地址十六進制地址
0x1
0xffffffff
0x7f000001
2
練習題8.1完成下表:點分十進制地址十六進制地址
0x1
5.因特網(wǎng)域名/*DNShostentrystructure,位于系統(tǒng)頭文件netdb.h*/structhostent{char*h_name;/*Officialdomainnameofhost*/char**h_aliases;/*Null-terminatedarrayofdomainname*/inth_addrtype;/*Hostaddresstype(AF_INET*/inth_length;/*Lengthofanaddress,inbytes*/char**h_addr_list;/*Null-terminatedarrayofin_addrstructs*/};5.因特網(wǎng)域名/*DNSh查詢域名和IP地址:(1)命令(1)API函數(shù)structhostent*gethostbyname(constchar*name);structhostent*gethostbyaddr(constchar*addr,intlen,0);查詢域名和IP地址:(1)命令(1)API函數(shù)structhostinfo.c#include"wrapper.h"intmain(intargc,char**argv){char**pp;structin_addraddr;structhostent*hostp;
if(argc!=2){…}
if(inet_aton(argv[1],&addr)!=0)hostp=Gethostbyaddr((constchar*)&addr,sizeof(addr),AF_INET);elsehostp=Gethostbyname(argv[1]);
printf("officialhostname:%s\n",hostp->h_name);for(pp=hostp->h_aliases;*pp!=NULL;pp++) printf("alias:%s\n",*pp);
for(pp=hostp->h_addr_list;*pp!=NULL;pp++){ addr.s_addr=*((unsignedint*)*pp); printf("address:%s\n",inet_ntoa(addr));}exit(0);}$./hostinfo31officialhostname:address:31$./hostinfoofficialhostname:address:address:28hostinfo.c#include"wrapper.h"8.3網(wǎng)絡通信API函數(shù)1、編程框架:8.3網(wǎng)絡通信API函數(shù)1、編程框架:2、網(wǎng)絡通信API函數(shù)(一)客戶端(1)創(chuàng)建套接字intsocket(intdomain,inttype,intprotocol);示例:client_sock=socket(AF_INET,SOCK_STREAM,0);(2)connect函數(shù)intconnect(intclient_sock,structsockaddr*serv_addr,intaddrlen);(3)包裝函數(shù)open_client_sock2、網(wǎng)絡通信API函數(shù)(一)客戶端intopen_client_sock(char*hostname,intport){intclient_sock;structhostent*hp;structsockaddr_inserveraddr;
if((client_sock=socket(AF_INET,SOCK_STREAM,0))<0) return-1;/*iferrorreturn-1*/
/*Fillintheserver'sIPaddressandport*/if((hp=gethostbyname(hostname))==NULL) return-2;/*iferrorreturn-2*/bzero((char*)&serveraddr,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;bcopy((char*)hp->h_addr_list[0], (char*)&serveraddr.sin_addr.s_addr,hp->h_length);serveraddr.sin_port=htons(port);
/*Establishaconnectionwiththeserver*/if(connect(client_sock,(SA*)&serveraddr,sizeof(se
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- Trilysine-TFA-生命科學試劑-MCE-4187
- KIF18A-IN-15-生命科學試劑-MCE-5317
- 4-4-Dimethoxyoctafluorobiphenyl-生命科學試劑-MCE-5198
- 1-3-Dinervonoyl-glycerol-生命科學試劑-MCE-1243
- 2025年度特色民宿體驗住宿協(xié)議
- 二零二五年度消防設備定制設計與銷售合同
- 二零二五年度農(nóng)產(chǎn)品線上線下一體化購銷合同標準
- 施工現(xiàn)場施工防傳染病傳播制度
- 個人兼職用工合同模板
- 鄉(xiāng)村別墅租賃合同樣本
- 《奧特萊斯業(yè)態(tài)淺析》課件
- 2022年湖南省公務員錄用考試《申論》真題(縣鄉(xiāng)卷)及答案解析
- 國家安全教育課程教學大綱分享
- 養(yǎng)殖場獸醫(yī)服務合同
- 電氣工程及其自動化基礎知識單選題100道及答案解析
- HR六大板塊+三支柱體系
- 慢性病患者門診身份管理方案
- 2025年高考英語一輪復習講義(新高考)第2部分語法第23講狀語從句(練習)(學生版+解析)
- 連鑄工職業(yè)技能大賽考試題庫-上(單選、多選題)
- 2024年全國統(tǒng)一高考數(shù)學試卷(新高考Ⅱ)含答案
- 十七個崗位安全操作規(guī)程手冊
評論
0/150
提交評論