![Linux编程-第8章-网络编程课件_第1页](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc1.gif)
![Linux编程-第8章-网络编程课件_第2页](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc2.gif)
![Linux编程-第8章-网络编程课件_第3页](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc3.gif)
![Linux编程-第8章-网络编程课件_第4页](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc4.gif)
![Linux编程-第8章-网络编程课件_第5页](http://file4.renrendoc.com/view/2d359e361f120a13144ec3f523f3a2bc/2d359e361f120a13144ec3f523f3a2bc5.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章网络编程本章概述本章的学习目标主要内容第8章网络编程本章概述本章学习目标理解网络通信结构和英特网连接,理解字节序、端口、套接字、IP地址、域名、客服端服务器模型等概念理解套接字地址结构,理解TCP网络通信程序构架,掌握套接字接口函数调用规范读懂网络通信示例程序,掌握简单网络应用编程方法理解简单HTML标记,理解URL,理解HTTP事务读懂和理解简单web服务器源代码,理解其工作原理,并进行实验验证本章学习目标理解网络通信结构和英特网连接,理解字节序、端口、本章主要内容网络通信结构套接字(socke)地址及设置网络编程API接口网络编程实例:toggleWEB编程基础小型web服务器weblet本章主要内容网络通信结构8.1网络通信结构Socket网络通信与IPC机制IPC机制:消息队列、共享内存、IPC信号量
结构麻烦、不易使用、仅用于同机进程间通信
仅用于Linux/Unix环境Socket网络通信:
标准、规范,基于TCP/IP协议
两种模式:TCP通信(与管道类似)UDP通信(与消息队列类似)
易于理解、使用,使用广泛
既可用于单机进程间通信,也可用于不同计算机
进程间通信
8.1网络通信结构Socket网络通信与IPC机制2.客户服务器模型
与网络通信一般采取客户服务器模型:2.客户服务器模型3.网络通信结构分层设计各层分工明确可靠性好,性能高3.网络通信结构分层设计4.套接字编程模型结构:网卡、TCP协议、套接字(Socket)类比:网卡(单位门牌号)、TCP/IP协议(收发室)、套接字(信箱号)套接字:含有进程接收信息的完整地址(Socket地址:IP地址、端口号)4.套接字编程模型结构:网卡、TCP协议、套接字(Socke5.因特网连接(TCP连接)TCP连接:比喻连接通信双方套接字的一条通信线路,
通信前建立,通信结束拆除一条TCP连接实际上就是一个文件描述符
可用read/write或send/recv进行数据收发地址:(cliaddr:cliport,servaddr:servport)5.因特网连接(TCP连接)TCP连接:比喻连接通信双方套接6.因特网连接实例(网页浏览)服务器端口号:规定为80客户端端口号:随机分配,123456.因特网连接实例(网页浏览)服务器端口号:规定为808.2套接字地址设置1.套接字地址结构:structsockaddr早期定义:16字节,适用于各种网络环境structsockaddr{unsignedshortsa_family;/*protocolfamily*/charsa_data[14];}2.适合Internet环境的套接字地址结构/*Intenet-stylesocketaddressstructure*/structsockaddr_in{unsignedshortsa_family;/*协议族,网络序*/unsignedshortsin_port;/*端口号,2字节,网络序*/
structin_addrsin_addr;/*IP地址,4字节,网络序
*/unsignedcharsin_zero[8];/*填充,8字节*/}structin_addr{unsignedints_addr;/*networkbyteorder(big-endian)*/};8.2套接字地址设置1.套接字地址结构:structs3.字节序(整数、浮点等)字符串:char*X=”ABCDEFGHIJ”‘A’‘B’‘C’‘J’…XX+1X+2X+9(1)问题的提出(主机序)整数: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.字节序(整数、浮点等)字符串:char*X=”ABC(2)大端模式、小端模式整数:unsignedintB[2]={0x12345678,0xabcdef},T=1234;void*A=(void*)B;unsignedint*K=(int*)malloc(sizeof(int));*K=0x12345678;大端模式(Big-Endian:高位在低地址字节,一般网络序)AA+4&TK小端模式(Little-Endian:高位在低地址字节,一般主机序):1234567800cdefab12D2345678AA+4&TK78563412efab00cd780456341204D2(2)大端模式、小端模式整数:unsignedintB(3)主机序、网络序转换unsignedlonginthtonl(unsignedlonginthostlong);unsignedshortinthtons(unsignedshortinthostshort);返回:按照网络字节顺序的值。unsignedlongintntohl(unsignedlongintnetlong);unsignedshortintntohs(unsigedshortintnetshort);h:hostn:networkl:long,int,4字节s:short,2字节(3)主机序、网络序转换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位整数(大端模式,网络序):structin_addrIP1=htonl(0x8002c2f2);128=0x80,2=0x02,193=0xc2,242=0xf2点分十进制:42转换函数:intinet_aton(constchar*cp,structin_addr*inp);char*inet_ntoa(structin_addrin);a:字符串n:32位整数8002c2f24.IP地址32位整数(大端模式,网络序):8002c2f练习题8.1完成下表:点分十进制地址十六进制地址
0x1
0xffffffff
0x7f000001
2
练习题8.1完成下表:点分十进制地址十六进制地址
0x1
5.因特网域名/*DNShostentrystructure,位于系统头文件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.因特网域名/*DNSh查询域名和IP地址:(1)命令(1)API函数structhostent*gethostbyname(constchar*name);structhostent*gethostbyaddr(constchar*addr,intlen,0);查询域名和IP地址:(1)命令(1)API函数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网络通信API函数1、编程框架:8.3网络通信API函数1、编程框架:2、网络通信API函数(一)客户端(1)创建套接字intsocket(intdomain,inttype,intprotocol);示例:client_sock=socket(AF_INET,SOCK_STREAM,0);(2)connect函数intconnect(intclient_sock,structsockaddr*serv_addr,intaddrlen);(3)包装函数open_client_sock2、网络通信API函数(一)客户端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包装函数:(二)服务器端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(三)数据收发(read/write、send/recv)ssize_tsend(intsock,constvoid*buff,size_tnbytes,intflags);
返回:若成功则为实际发送字节数,若出错则为SOCKET_ERROR.ssize_trecv(intsock,void*buff,size_tnbytes,intflags);
返回:若成功返回实际接收字节数,若出错则为SOCKET_ERROR,如果recv函数在等待协议接收数据时网络中断了,则返回0(三)数据收发(read/write、send/recv)s8.4网络编程实例:toggle应用功能描述:客户端togglec.c将从标准输入读到的字符串发送给服务端togglei.c,服务端将收到的字符串进行中的英文字母小写转大写、大写转小写后发给客户端显示出来。8.4网络编程实例: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编写一个网络通信程序,客户端从服务器端取指定文件保存,并显示输出。练习题8.5编写一个网络通信程序,客户端将指定文件上传到服务器端,服务器保存和输出文件内容。*练习题8.6查阅资料,采用UDP协议实现toggle客户端和服务器。练习题8.4编写一个网络通信程序,客户端从服务器端取指8.5Web编程基础0.为何要用web编程前述网络编程方法:客户与服务器间传送数据的含义由双方预先约定应用升级要重新修改和部署服务器与客户端一般客户端分发和升级比较麻烦Web编程优点:只需开发服务器端,客户端为浏览器如果升级只需直接升级服务器端服务器端与客户端之间有规范的通信协议8.5Web编程基础0.为何要用web编程1.Web基础(1)数据传递方法一般文本数据用超文本交互语言(html)文件传递。hello.html:<html><head><title>asimplepagefortestingweblet</title><head><body>Hello,<ahref=>dgut</a></body></html>显示输出:1.Web基础(1)数据传递方法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内容的过程:A.静态网页http://:80/index.html协议服务器地址服务器端口号缺省为80资源路径和文件名,缺省为/index.html含义:用http协议请求服务器上web网站目录/下index.html文件B.动态网页http://:8000/cgi-bin/add?2017&523808协议服务器地址服务器端口号资源路径和文件名参数含义:运行上web网站目录/cgi-bin下的add程序,命令行参数为2017和523808,由该程序产生html格式内容,发送给浏览器(2)web(一般指服务器)提供Web内容的过程:协议服务器(3)HTTP事务http协议:在传输网页内容之前,先需在浏览器和WEB服务器间进行多次数据交换,达成某种共识,但用户看不见整个传输过程为http事务可用telnet验证,以访问百度网站为例(3)HTTP事务http协议:1$telent80Client:请求连接百度web服务器2Trying12...telnet打印三行信息3Connectedto.4Escapecharacteris'^]'.5GET/HTTP/1.1Client:基于http1.1协议用GET方法请求网页/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.主函数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.主函数main2.处理http事务(process_trans函数)(1)处理请求行voidprocess_trans(intfd)//fd为网络连接{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函数)(1)(2)如何处理其他请求头(read_requesthdrs函数)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);//否则结束循环
}return;}(2)如何处理其他请求头(read_requesthdrs函(3)判断静态/动态网页(process_trans函数)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;}判断是否为静态网页请求行为:80/index.html时,uri=/index.html请求行为:8000/cgi-bin/add?2017&523808时,uri=/cgi-bin/add?2017&523808(3)判断静态/动态网页(process_trans函数)(4)uri路径处理,得到文件路径filename处理静态网页路径(parse_static_uri函数):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处理静态网处理动态网页路径(parse_dynamic_uri函数):
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);}动态路径的uri中必有?字符,以uri=/cgi-bin/add?2017&523808为例:执行该函数后,cgiargs=“2017%523808”filename=./cgi-bin/add处理动态网页路径(parse_dynamic_uri函数):(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)如何返回静态网页(feed_static函数)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)如何返回静态网页(feed_static函数)void(7)静态网页功能测试A.准备测试网页test.html,置于与weblet所在目录:<html><head><title>asimplepagefortestingweblet</title><head><body>HelloWorld</body></html>B.编译和运行weblet$gcc-owebletweblet.c-L.-lwrapper$./weblet12345C.用浏览器测试(7)静态网页功能测试A.准备测试网页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行代码,将状态码、文件大小、文件类型、写入fd的buf长度与实际不同,通过浏览器和telnet,请求网页test.html,观察服务器响应和浏览器显示结果,并给出解释。练习题8.9阅读图8-18源代码,修改第8、10、11、1(7)如何返回动态网页(feed_dynamic函数)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为网络连接*/ execve(filename,emptylist,environ);/*加载运行CGI程序/cgi-bin/add*/}close(pfd[0]);write(pfd[1],cgiargs,strlen(cgiargs)+1);//通过管道把参数传递给CGI程序wait(NULL);/*Parentwaitsforandreapschild*/close(pfd[1]);}(7)如何返回动态网页(feed_dynamic函数)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参数为:2017%523808产生text/html内容(7)cgi程序addintmain(void){(8)动态网页测试A.编译和执行服务器:$gcc-owebletweblet.c-L.-lwrapper$gcc-oaddadd.c$mkdircgi-bin$cpaddcgi-bin$
./weblet12345B.用浏览器测试(8)动态网页测试A.编译和执行服务器: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实现CGI程序add,并调试之。练习题8.11编写和运行CGI程序,在浏览器中显示指定ls命令的内容;编写CGI程序,能通过浏览器输入Linux命令,在浏览器显示命令输出。*练习题8.12输入命令“./weblet12345”启动weblet,用一个telnet进程来连接weblet,并输入网页浏览请求,在该请求处理未完成前,在浏览器地址栏输入http://localhost:12345/test.html,将看到什么结果,并予以解释*8.21修改toggle服务器代码,使之每次向客户端回送文本行,后接当前系统时间。练习题8.10用shell或python实现CGI程序aTheEndTheEnd第8章网络编程本章概述本章的学习目标主要内容第8章网络编程本章概述本章学习目标理解网络通信结构和英特网连接,理解字节序、端口、套接字、IP地址、域名、客服端服务器模型等概念理解套接字地址结构,理解TCP网络通信程序构架,掌握套接字接口函数调用规范读懂网络通信示例程序,掌握简单网络应用编程方法理解简单HTML标记,理解URL,理解HTTP事务读懂和理解简单web服务器源代码,理解其工作原理,并进行实验验证本章学习目标理解网络通信结构和英特网连接,理解字节序、端口、本章主要内容网络通信结构套接字(socke)地址及设置网络编程API接口网络编程实例:toggleWEB编程基础小型web服务器weblet本章主要内容网络通信结构8.1网络通信结构Socket网络通信与IPC机制IPC机制:消息队列、共享内存、IPC信号量
结构麻烦、不易使用、仅用于同机进程间通信
仅用于Linux/Unix环境Socket网络通信:
标准、规范,基于TCP/IP协议
两种模式:TCP通信(与管道类似)UDP通信(与消息队列类似)
易于理解、使用,使用广泛
既可用于单机进程间通信,也可用于不同计算机
进程间通信
8.1网络通信结构Socket网络通信与IPC机制2.客户服务器模型
与网络通信一般采取客户服务器模型:2.客户服务器模型3.网络通信结构分层设计各层分工明确可靠性好,性能高3.网络通信结构分层设计4.套接字编程模型结构:网卡、TCP协议、套接字(Socket)类比:网卡(单位门牌号)、TCP/IP协议(收发室)、套接字(信箱号)套接字:含有进程接收信息的完整地址(Socket地址:IP地址、端口号)4.套接字编程模型结构:网卡、TCP协议、套接字(Socke5.因特网连接(TCP连接)TCP连接:比喻连接通信双方套接字的一条通信线路,
通信前建立,通信结束拆除一条TCP连接实际上就是一个文件描述符
可用read/write或send/recv进行数据收发地址:(cliaddr:cliport,servaddr:servport)5.因特网连接(TCP连接)TCP连接:比喻连接通信双方套接6.因特网连接实例(网页浏览)服务器端口号:规定为80客户端端口号:随机分配,123456.因特网连接实例(网页浏览)服务器端口号:规定为808.2套接字地址设置1.套接字地址结构:structsockaddr早期定义:16字节,适用于各种网络环境structsockaddr{unsignedshortsa_family;/*protocolfamily*/charsa_data[14];}2.适合Internet环境的套接字地址结构/*Intenet-stylesocketaddressstructure*/structsockaddr_in{unsignedshortsa_family;/*协议族,网络序*/unsignedshortsin_port;/*端口号,2字节,网络序*/
structin_addrsin_addr;/*IP地址,4字节,网络序
*/unsignedcharsin_zero[8];/*填充,8字节*/}structin_addr{unsignedints_addr;/*networkbyteorder(big-endian)*/};8.2套接字地址设置1.套接字地址结构:structs3.字节序(整数、浮点等)字符串:char*X=”ABCDEFGHIJ”‘A’‘B’‘C’‘J’…XX+1X+2X+9(1)问题的提出(主机序)整数: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.字节序(整数、浮点等)字符串:char*X=”ABC(2)大端模式、小端模式整数:unsignedintB[2]={0x12345678,0xabcdef},T=1234;void*A=(void*)B;unsignedint*K=(int*)malloc(sizeof(int));*K=0x12345678;大端模式(Big-Endian:高位在低地址字节,一般网络序)AA+4&TK小端模式(Little-Endian:高位在低地址字节,一般主机序):1234567800cdefab12D2345678AA+4&TK78563412efab00cd780456341204D2(2)大端模式、小端模式整数:unsignedintB(3)主机序、网络序转换unsignedlonginthtonl(unsignedlonginthostlong);unsignedshortinthtons(unsignedshortinthostshort);返回:按照网络字节顺序的值。unsignedlongintntohl(unsignedlongintnetlong);unsignedshortintntohs(unsigedshortintnetshort);h:hostn:networkl:long,int,4字节s:short,2字节(3)主机序、网络序转换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位整数(大端模式,网络序):structin_addrIP1=htonl(0x8002c2f2);128=0x80,2=0x02,193=0xc2,242=0xf2点分十进制:42转换函数:intinet_aton(constchar*cp,structin_addr*inp);char*inet_ntoa(structin_addrin);a:字符串n:32位整数8002c2f24.IP地址32位整数(大端模式,网络序):8002c2f练习题8.1完成下表:点分十进制地址十六进制地址
0x1
0xffffffff
0x7f000001
2
练习题8.1完成下表:点分十进制地址十六进制地址
0x1
5.因特网域名/*DNShostentrystructure,位于系统头文件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.因特网域名/*DNSh查询域名和IP地址:(1)命令(1)API函数structhostent*gethostbyname(constchar*name);structhostent*gethostbyaddr(constchar*addr,intlen,0);查询域名和IP地址:(1)命令(1)API函数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网络通信API函数1、编程框架:8.3网络通信API函数1、编程框架:2、网络通信API函数(一)客户端(1)创建套接字intsocket(intdomain,inttype,intprotocol);示例:client_sock=socket(AF_INET,SOCK_STREAM,0);(2)connect函数intconnect(intclient_sock,structsockaddr*serv_addr,intaddrlen);(3)包装函数open_client_sock2、网络通信API函数(一)客户端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. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度学生保险居间业务合同
- 教育培训行业经验分享指南
- 汽车汽车租赁合同
- 三农村电商物流作业指导书
- 转租房屋租赁合同
- 矿业与安全技术作业指导书
- 房地产中介销售服务合同
- 电子电路设计与制造作业指导书
- 组织行为学作业指导书
- 双语艺术节之迎新文艺晚会活动方案
- 2025年高考英语一轮复习讲义(新高考)第2部分语法第23讲状语从句(练习)(学生版+解析)
- NB/T 11459-2023煤矿井下直流电法勘探规程
- 十七个岗位安全操作规程手册
- 爆花(2023年陕西中考语文试卷记叙文阅读题及答案)
- 自主签到培训课件-早安!幼儿园
- 小学项目化学习案例
- 2024-2030年中国大宗商品行业市场深度调研及发展趋势与投资前景研究报告
- 强化提升1解三角形中的三线问题(解析)
- 异地就医备案的个人承诺书
- 2024-2030年中国ODM服务器行业市场发展分析及前景趋势与投资研究报告
- 室内装饰拆除专项施工方案
评论
0/150
提交评论