版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第8章網(wǎng)絡(luò)編程本章概述本章的學(xué)習(xí)目標(biāo)主要內(nèi)容第8章網(wǎng)絡(luò)編程本章概述本章學(xué)習(xí)目標(biāo)理解網(wǎng)絡(luò)通信結(jié)構(gòu)和英特網(wǎng)連接,理解字節(jié)序、端口、套接字、IP地址、域名、客服端服務(wù)器模型等概念理解套接字地址結(jié)構(gòu),理解TCP網(wǎng)絡(luò)通信程序構(gòu)架,掌握套接字接口函數(shù)調(diào)用規(guī)范讀懂網(wǎng)絡(luò)通信示例程序,掌握簡單網(wǎng)絡(luò)應(yīng)用編程方法理解簡單HTML標(biāo)記,理解URL,理解HTTP事務(wù)讀懂和理解簡單web服務(wù)器源代碼,理解其工作原理,并進(jìn)行實(shí)驗(yàn)驗(yàn)證本章學(xué)習(xí)目標(biāo)理解網(wǎng)絡(luò)通信結(jié)構(gòu)和英特網(wǎng)連接,理解字節(jié)序、端口、本章主要內(nèi)容網(wǎng)絡(luò)通信結(jié)構(gòu)套接字(socke)地址及設(shè)置網(wǎng)絡(luò)編程API接口網(wǎng)絡(luò)編程實(shí)例:toggleWEB編程基礎(chǔ)小型web服務(wù)器weblet本章主要內(nèi)容網(wǎng)絡(luò)通信結(jié)構(gòu)8.1網(wǎng)絡(luò)通信結(jié)構(gòu)Socket網(wǎng)絡(luò)通信與IPC機(jī)制IPC機(jī)制:消息隊(duì)列、共享內(nèi)存、IPC信號量
結(jié)構(gòu)麻煩、不易使用、僅用于同機(jī)進(jìn)程間通信
僅用于Linux/Unix環(huán)境Socket網(wǎng)絡(luò)通信:
標(biāo)準(zhǔn)、規(guī)范,基于TCP/IP協(xié)議
兩種模式:TCP通信(與管道類似)UDP通信(與消息隊(duì)列類似)
易于理解、使用,使用廣泛
既可用于單機(jī)進(jìn)程間通信,也可用于不同計算機(jī)
進(jìn)程間通信
8.1網(wǎng)絡(luò)通信結(jié)構(gòu)Socket網(wǎng)絡(luò)通信與IPC機(jī)制2.客戶服務(wù)器模型
與網(wǎng)絡(luò)通信一般采取客戶服務(wù)器模型:2.客戶服務(wù)器模型3.網(wǎng)絡(luò)通信結(jié)構(gòu)分層設(shè)計各層分工明確可靠性好,性能高3.網(wǎng)絡(luò)通信結(jié)構(gòu)分層設(shè)計4.套接字編程模型結(jié)構(gòu):網(wǎng)卡、TCP協(xié)議、套接字(Socket)類比:網(wǎng)卡(單位門牌號)、TCP/IP協(xié)議(收發(fā)室)、套接字(信箱號)套接字:含有進(jìn)程接收信息的完整地址(Socket地址:IP地址、端口號)4.套接字編程模型結(jié)構(gòu):網(wǎng)卡、TCP協(xié)議、套接字(Socke5.因特網(wǎng)連接(TCP連接)TCP連接:比喻連接通信雙方套接字的一條通信線路,
通信前建立,通信結(jié)束拆除一條TCP連接實(shí)際上就是一個文件描述符
可用read/write或send/recv進(jìn)行數(shù)據(jù)收發(fā)地址:(cliaddr:cliport,servaddr:servport)5.因特網(wǎng)連接(TCP連接)TCP連接:比喻連接通信雙方套接6.因特網(wǎng)連接實(shí)例(網(wǎng)頁瀏覽)服務(wù)器端口號:規(guī)定為80客戶端端口號:隨機(jī)分配,123456.因特網(wǎng)連接實(shí)例(網(wǎng)頁瀏覽)服務(wù)器端口號:規(guī)定為808.2套接字地址設(shè)置1.套接字地址結(jié)構(gòu):structsockaddr早期定義:16字節(jié),適用于各種網(wǎng)絡(luò)環(huán)境structsockaddr{unsignedshortsa_family;/*protocolfamily*/charsa_data[14];}2.適合Internet環(huán)境的套接字地址結(jié)構(gòu)/*Intenet-stylesocketaddressstructure*/structsockaddr_in{unsignedshortsa_family;/*協(xié)議族,網(wǎng)絡(luò)序*/unsignedshortsin_port;/*端口號,2字節(jié),網(wǎng)絡(luò)序*/
structin_addrsin_addr;/*IP地址,4字節(jié),網(wǎng)絡(luò)序
*/unsignedcharsin_zero[8];/*填充,8字節(jié)*/}structin_addr{unsignedints_addr;/*networkbyteorder(big-endian)*/};8.2套接字地址設(shè)置1.套接字地址結(jié)構(gòu):structs3.字節(jié)序(整數(shù)、浮點(diǎn)等)字符串:char*X=”ABCDEFGHIJ”‘A’‘B’‘C’‘J’…XX+1X+2X+9(1)問題的提出(主機(jī)序)整數(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ù)、浮點(diǎn)等)字符串: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)絡(luò)序)AA+4&TK小端模式(Little-Endian:高位在低地址字節(jié),一般主機(jī)序):1234567800cdefab12D2345678AA+4&TK78563412efab00cd780456341204D2(2)大端模式、小端模式整數(shù):unsignedintB(3)主機(jī)序、網(wǎng)絡(luò)序轉(zhuǎn)換unsignedlonginthtonl(unsignedlonginthostlong);unsignedshortinthtons(unsignedshortinthostshort);返回:按照網(wǎng)絡(luò)字節(jié)順序的值。unsignedlongintntohl(unsignedlongintnetlong);unsignedshortintntohs(unsigedshortintnetshort);h:hostn:networkl:long,int,4字節(jié)s:short,2字節(jié)(3)主機(jī)序、網(wǎng)絡(luò)序轉(zhuǎn)換unsignedlongint練習(xí)題8.3閱讀下面代碼,假設(shè)主機(jī)采用小端模式,分析運(yùn)行結(jié)果,并給出解釋:#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);}練習(xí)題8.3閱讀下面代碼,假設(shè)主機(jī)采用小端模式,分析運(yùn)行結(jié)4.IP地址32位整數(shù)(大端模式,網(wǎng)絡(luò)序):structin_addrIP1=htonl(0x8002c2f2);128=0x80,2=0x02,193=0xc2,242=0xf2點(diǎn)分十進(jìn)制: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)絡(luò)序):8002c2f練習(xí)題8.1完成下表:點(diǎn)分十進(jìn)制地址十六進(jìn)制地址
0x1
0xffffffff
0x7f000001
2
練習(xí)題8.1完成下表:點(diǎn)分十進(jìn)制地址十六進(jìn)制地址
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)絡(luò)通信API函數(shù)1、編程框架:8.3網(wǎng)絡(luò)通信API函數(shù)1、編程框架:2、網(wǎng)絡(luò)通信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)絡(luò)通信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(二)服務(wù)器端intbind(intserv_sock,structsockaddr*my_addr,intaddrlen);intlisten(intserv_sock,intbacklog);
open_listen_sock包裝函數(shù):(二)服務(wù)器端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);
返回:若成功則為實(shí)際發(fā)送字節(jié)數(shù),若出錯則為SOCKET_ERROR.ssize_trecv(intsock,void*buff,size_tnbytes,intflags);
返回:若成功返回實(shí)際接收字節(jié)數(shù),若出錯則為SOCKET_ERROR,如果recv函數(shù)在等待協(xié)議接收數(shù)據(jù)時網(wǎng)絡(luò)中斷了,則返回0(三)數(shù)據(jù)收發(fā)(read/write、send/recv)s8.4網(wǎng)絡(luò)編程實(shí)例:toggle應(yīng)用功能描述:客戶端togglec.c將從標(biāo)準(zhǔn)輸入讀到的字符串發(fā)送給服務(wù)端togglei.c,服務(wù)端將收到的字符串進(jìn)行中的英文字母小寫轉(zhuǎn)大寫、大寫轉(zhuǎn)小寫后發(fā)給客戶端顯示出來。8.4網(wǎng)絡(luò)編程實(shí)例:toggle應(yīng)用功能描述:客戶端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);}服務(wù)器端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編譯、運(yùn)行$gcc-otogglectogglec.c-L.-lwrapper$gcc-otogglesitogglesi.ctoggle.c-L.-lwrapper編譯、運(yùn)行$gcc-otogglectogg練習(xí)題8.4編寫一個網(wǎng)絡(luò)通信程序,客戶端從服務(wù)器端取指定文件保存,并顯示輸出。練習(xí)題8.5編寫一個網(wǎng)絡(luò)通信程序,客戶端將指定文件上傳到服務(wù)器端,服務(wù)器保存和輸出文件內(nèi)容。*練習(xí)題8.6查閱資料,采用UDP協(xié)議實(shí)現(xiàn)toggle客戶端和服務(wù)器。練習(xí)題8.4編寫一個網(wǎng)絡(luò)通信程序,客戶端從服務(wù)器端取指8.5Web編程基礎(chǔ)0.為何要用web編程前述網(wǎng)絡(luò)編程方法:客戶與服務(wù)器間傳送數(shù)據(jù)的含義由雙方預(yù)先約定應(yīng)用升級要重新修改和部署服務(wù)器與客戶端一般客戶端分發(fā)和升級比較麻煩Web編程優(yōu)點(diǎn):只需開發(fā)服務(wù)器端,客戶端為瀏覽器如果升級只需直接升級服務(wù)器端服務(wù)器端與客戶端之間有規(guī)范的通信協(xié)議8.5Web編程基礎(chǔ)0.為何要用web編程1.Web基礎(chǔ)(1)數(shù)據(jù)傳遞方法一般文本數(shù)據(jù)用超文本交互語言(html)文件傳遞。hello.html:<html><head><title>asimplepagefortestingweblet</title><head><body>Hello,<ahref=>dgut</a></body></html>顯示輸出:1.Web基礎(chǔ)(1)數(shù)據(jù)傳遞方法hello.html:顯示也可傳遞其他類型信息:常用MIME類型MIME類型描述text/htmltext/plainapplication/pdfimage/gifimage/jpeggzapplication/x-gzipvideo/mpeg.text/xmlhtml頁面無格式文本(如.txt文件)pdf文檔gif格式編碼的二進(jìn)制圖像jpeg格式編碼的二進(jìn)制圖像GZIP文件:
.gzMPEG文件:mpg,.mpegxml文件:.xml也可傳遞其他類型信息:常用MIME類型MIME類型描述tex(2)web(一般指服務(wù)器)提供Web內(nèi)容的過程:A.靜態(tài)網(wǎng)頁http://:80/index.html協(xié)議服務(wù)器地址服務(wù)器端口號缺省為80資源路徑和文件名,缺省為/index.html含義:用http協(xié)議請求服務(wù)器上web網(wǎng)站目錄/下index.html文件B.動態(tài)網(wǎng)頁http://:8000/cgi-bin/add?2017&523808協(xié)議服務(wù)器地址服務(wù)器端口號資源路徑和文件名參數(shù)含義:運(yùn)行上web網(wǎng)站目錄/cgi-bin下的add程序,命令行參數(shù)為2017和523808,由該程序產(chǎn)生html格式內(nèi)容,發(fā)送給瀏覽器(2)web(一般指服務(wù)器)提供Web內(nèi)容的過程:協(xié)議服務(wù)器(3)HTTP事務(wù)http協(xié)議:在傳輸網(wǎng)頁內(nèi)容之前,先需在瀏覽器和WEB服務(wù)器間進(jìn)行多次數(shù)據(jù)交換,達(dá)成某種共識,但用戶看不見整個傳輸過程為http事務(wù)可用telnet驗(yàn)證,以訪問百度網(wǎng)站為例(3)HTTP事務(wù)http協(xié)議:1$telent80Client:請求連接百度web服務(wù)器2Trying12...telnet打印三行信息3Connectedto.4Escapecharacteris'^]'.5GET/HTTP/1.1Client:基于http1.1協(xié)議用GET方法請求網(wǎng)頁/index.html6HOST:WWW.BAIDU.COMClient:給出主機(jī)域名地址,這些都不顯示7Client:請求行用回車空行表示結(jié)束HTTP/1.1200OKServer:服務(wù)器響應(yīng)行,200
OK表示無誤Date:Sun,06Aug201704:05:08GMTServer:幾個響應(yīng)頭:時間、Content-Type:text/html類型:text/html
Content-Length:14613
返回文件index.html長度12Last-Modified:Thu,27Jul201704:30:00GMT最后修改時間13…14Accept-Ranges:bytes15Server:響應(yīng)頭用空行結(jié)尾16<html>Server:響應(yīng)體(index.html)開始17<head>18…19</body></html>Server:lastlineinresponsebody20Connectionclosedbyforeignhost.Server:關(guān)閉連接提示21$Clinet:closeconnectionandterminates1$telent80七、小型Web服務(wù)器: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服務(wù)器:weblet.c1.主函數(shù)main2.處理http事務(wù)(process_trans函數(shù))(1)處理請求行voidprocess_trans(intfd)//fd為網(wǎng)絡(luò)連接{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事務(wù)(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);//否則結(jié)束循環(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.準(zhǔn)備測試網(wǎng)頁test.html,置于與weblet所在目錄:<html><head><title>asimplepagefortestingweblet</title><head><body>HelloWorld</body></html>B.編譯和運(yùn)行weblet$gcc-owebletweblet.c-L.-lwrapper$./weblet12345C.用瀏覽器測試(7)靜態(tài)網(wǎng)頁功能測試A.準(zhǔn)備測試網(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練習(xí)題8.9閱讀圖8-18源代碼,修改第8、10、11、12行代碼,將狀態(tài)碼、文件大小、文件類型、寫入fd的buf長度與實(shí)際不同,通過瀏覽器和telnet,請求網(wǎng)頁test.html,觀察服務(wù)器響應(yīng)和瀏覽器顯示結(jié)果,并給出解釋。練習(xí)題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)絡(luò)連接*/ execve(filename,emptylist,environ);/*加載運(yùn)行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í)行服務(wù)器:$gcc-owebletweblet.c-L.-lwrapper$gcc-oaddadd.c$mkdircgi-bin$cpaddcgi-bin$
./weblet12345B.用瀏覽器測試(8)動態(tài)網(wǎng)頁測試A.編譯和執(zhí)行服務(wù)器: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練習(xí)題8.10用shell或python實(shí)現(xiàn)CGI程序add,并調(diào)試之。練習(xí)題8.11編寫和運(yùn)行CGI程序,在瀏覽器中顯示指定ls命令的內(nèi)容;編寫CGI程序,能通過瀏覽器輸入Linux命令,在瀏覽器顯示命令輸出。*練習(xí)題8.12輸入命令“./weblet12345”啟動weblet,用一個telnet進(jìn)程來連接weblet,并輸入網(wǎng)頁瀏覽請求,在該請求處理未完成前,在瀏覽器地址欄輸入http://localhost:12345/test.html,將看到什么結(jié)果,并予以解釋*8.21修改toggle服務(wù)器代碼,使之每次向客戶端回送文本行,后接當(dāng)前系統(tǒng)時間。練習(xí)題8.10用shell或python實(shí)現(xiàn)CGI程序aTheEndTheEnd第8章網(wǎng)絡(luò)編程本章概述本章的學(xué)習(xí)目標(biāo)主要內(nèi)容第8章網(wǎng)絡(luò)編程本章概述本章學(xué)習(xí)目標(biāo)理解網(wǎng)絡(luò)通信結(jié)構(gòu)和英特網(wǎng)連接,理解字節(jié)序、端口、套接字、IP地址、域名、客服端服務(wù)器模型等概念理解套接字地址結(jié)構(gòu),理解TCP網(wǎng)絡(luò)通信程序構(gòu)架,掌握套接字接口函數(shù)調(diào)用規(guī)范讀懂網(wǎng)絡(luò)通信示例程序,掌握簡單網(wǎng)絡(luò)應(yīng)用編程方法理解簡單HTML標(biāo)記,理解URL,理解HTTP事務(wù)讀懂和理解簡單web服務(wù)器源代碼,理解其工作原理,并進(jìn)行實(shí)驗(yàn)驗(yàn)證本章學(xué)習(xí)目標(biāo)理解網(wǎng)絡(luò)通信結(jié)構(gòu)和英特網(wǎng)連接,理解字節(jié)序、端口、本章主要內(nèi)容網(wǎng)絡(luò)通信結(jié)構(gòu)套接字(socke)地址及設(shè)置網(wǎng)絡(luò)編程API接口網(wǎng)絡(luò)編程實(shí)例:toggleWEB編程基礎(chǔ)小型web服務(wù)器weblet本章主要內(nèi)容網(wǎng)絡(luò)通信結(jié)構(gòu)8.1網(wǎng)絡(luò)通信結(jié)構(gòu)Socket網(wǎng)絡(luò)通信與IPC機(jī)制IPC機(jī)制:消息隊(duì)列、共享內(nèi)存、IPC信號量
結(jié)構(gòu)麻煩、不易使用、僅用于同機(jī)進(jìn)程間通信
僅用于Linux/Unix環(huán)境Socket網(wǎng)絡(luò)通信:
標(biāo)準(zhǔn)、規(guī)范,基于TCP/IP協(xié)議
兩種模式:TCP通信(與管道類似)UDP通信(與消息隊(duì)列類似)
易于理解、使用,使用廣泛
既可用于單機(jī)進(jìn)程間通信,也可用于不同計算機(jī)
進(jìn)程間通信
8.1網(wǎng)絡(luò)通信結(jié)構(gòu)Socket網(wǎng)絡(luò)通信與IPC機(jī)制2.客戶服務(wù)器模型
與網(wǎng)絡(luò)通信一般采取客戶服務(wù)器模型:2.客戶服務(wù)器模型3.網(wǎng)絡(luò)通信結(jié)構(gòu)分層設(shè)計各層分工明確可靠性好,性能高3.網(wǎng)絡(luò)通信結(jié)構(gòu)分層設(shè)計4.套接字編程模型結(jié)構(gòu):網(wǎng)卡、TCP協(xié)議、套接字(Socket)類比:網(wǎng)卡(單位門牌號)、TCP/IP協(xié)議(收發(fā)室)、套接字(信箱號)套接字:含有進(jìn)程接收信息的完整地址(Socket地址:IP地址、端口號)4.套接字編程模型結(jié)構(gòu):網(wǎng)卡、TCP協(xié)議、套接字(Socke5.因特網(wǎng)連接(TCP連接)TCP連接:比喻連接通信雙方套接字的一條通信線路,
通信前建立,通信結(jié)束拆除一條TCP連接實(shí)際上就是一個文件描述符
可用read/write或send/recv進(jìn)行數(shù)據(jù)收發(fā)地址:(cliaddr:cliport,servaddr:servport)5.因特網(wǎng)連接(TCP連接)TCP連接:比喻連接通信雙方套接6.因特網(wǎng)連接實(shí)例(網(wǎng)頁瀏覽)服務(wù)器端口號:規(guī)定為80客戶端端口號:隨機(jī)分配,123456.因特網(wǎng)連接實(shí)例(網(wǎng)頁瀏覽)服務(wù)器端口號:規(guī)定為808.2套接字地址設(shè)置1.套接字地址結(jié)構(gòu):structsockaddr早期定義:16字節(jié),適用于各種網(wǎng)絡(luò)環(huán)境structsockaddr{unsignedshortsa_family;/*protocolfamily*/charsa_data[14];}2.適合Internet環(huán)境的套接字地址結(jié)構(gòu)/*Intenet-stylesocketaddressstructure*/structsockaddr_in{unsignedshortsa_family;/*協(xié)議族,網(wǎng)絡(luò)序*/unsignedshortsin_port;/*端口號,2字節(jié),網(wǎng)絡(luò)序*/
structin_addrsin_addr;/*IP地址,4字節(jié),網(wǎng)絡(luò)序
*/unsignedcharsin_zero[8];/*填充,8字節(jié)*/}structin_addr{unsignedints_addr;/*networkbyteorder(big-endian)*/};8.2套接字地址設(shè)置1.套接字地址結(jié)構(gòu):structs3.字節(jié)序(整數(shù)、浮點(diǎn)等)字符串:char*X=”ABCDEFGHIJ”‘A’‘B’‘C’‘J’…XX+1X+2X+9(1)問題的提出(主機(jī)序)整數(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ù)、浮點(diǎn)等)字符串: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)絡(luò)序)AA+4&TK小端模式(Little-Endian:高位在低地址字節(jié),一般主機(jī)序):1234567800cdefab12D2345678AA+4&TK78563412efab00cd780456341204D2(2)大端模式、小端模式整數(shù):unsignedintB(3)主機(jī)序、網(wǎng)絡(luò)序轉(zhuǎn)換unsignedlonginthtonl(unsignedlonginthostlong);unsignedshortinthtons(unsignedshortinthostshort);返回:按照網(wǎng)絡(luò)字節(jié)順序的值。unsignedlongintntohl(unsignedlongintnetlong);unsignedshortintntohs(unsigedshortintnetshort);h:hostn:networkl:long,int,4字節(jié)s:short,2字節(jié)(3)主機(jī)序、網(wǎng)絡(luò)序轉(zhuǎn)換unsignedlongint練習(xí)題8.3閱讀下面代碼,假設(shè)主機(jī)采用小端模式,分析運(yùn)行結(jié)果,并給出解釋:#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);}練習(xí)題8.3閱讀下面代碼,假設(shè)主機(jī)采用小端模式,分析運(yùn)行結(jié)4.IP地址32位整數(shù)(大端模式,網(wǎng)絡(luò)序):structin_addrIP1=htonl(0x8002c2f2);128=0x80,2=0x02,193=0xc2,242=0xf2點(diǎn)分十進(jìn)制: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)絡(luò)序):8002c2f練習(xí)題8.1完成下表:點(diǎn)分十進(jìn)制地址十六進(jìn)制地址
0x1
0xffffffff
0x7f000001
2
練習(xí)題8.1完成下表:點(diǎn)分十進(jìn)制地址十六進(jìn)制地址
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)絡(luò)通信API函數(shù)1、編程框架:8.3網(wǎng)絡(luò)通信API函數(shù)1、編程框架:2、網(wǎng)絡(luò)通信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)絡(luò)通信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)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 散裝行業(yè)話務(wù)員工作總結(jié)
- 2025-2030全球IP66工業(yè)平板電腦行業(yè)調(diào)研及趨勢分析報告
- 2025年全球及中國1,1,1,2,3,3,3-七氟丙烷行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 2025年全球及中國可移動游泳池地板行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 2025-2030全球噴丸研磨石行業(yè)調(diào)研及趨勢分析報告
- 2025年全球及中國超聲波和熱熔嵌件行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 2025-2030全球振動供料系統(tǒng)行業(yè)調(diào)研及趨勢分析報告
- 2025年全球及中國晶圓旋轉(zhuǎn)清洗機(jī)行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 2025年全球及中國振動脫油機(jī)行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 2025年全球及中國藝術(shù)品和古董搬運(yùn)服務(wù)行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 人教版2024-2025學(xué)年八年級上學(xué)期數(shù)學(xué)期末壓軸題練習(xí)
- 【人教版化學(xué)】必修1 知識點(diǎn)默寫小紙條(答案背誦版)
- 江蘇省無錫市2023-2024學(xué)年八年級上學(xué)期期末數(shù)學(xué)試題(原卷版)
- 全國第三屆職業(yè)技能大賽(無人機(jī)駕駛(植保)項(xiàng)目)選拔賽理論考試題庫(含答案)
- 《奧特萊斯業(yè)態(tài)淺析》課件
- 2022年湖南省公務(wù)員錄用考試《申論》真題(縣鄉(xiāng)卷)及答案解析
- 國家安全教育課程教學(xué)大綱分享
- 養(yǎng)殖場獸醫(yī)服務(wù)合同
- 電氣工程及其自動化基礎(chǔ)知識單選題100道及答案解析
- HR六大板塊+三支柱體系
評論
0/150
提交評論