第06章名字與地址轉(zhuǎn)換編程_第1頁
第06章名字與地址轉(zhuǎn)換編程_第2頁
第06章名字與地址轉(zhuǎn)換編程_第3頁
第06章名字與地址轉(zhuǎn)換編程_第4頁
第06章名字與地址轉(zhuǎn)換編程_第5頁
已閱讀5頁,還剩48頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

第6章

名字與地址轉(zhuǎn)換編程知識點:

域名系統(tǒng)作用域名系統(tǒng)對應記錄從域名解析對應IP從IP解析對應域名現(xiàn)在的網(wǎng)絡都是使用名字來訪問服務器的,而不是使用地址來訪問。那它們是怎么轉(zhuǎn)換的呢?答案就是利用名字與地址的轉(zhuǎn)換函數(shù)實現(xiàn)的:gethostbyname和gethostbyaddr在主機名字與IP地址間進行轉(zhuǎn)換,getservbyname和getservbyport在服務名字和端口號間進行轉(zhuǎn)換,并且還要介紹兩個與協(xié)議無關的getaddrinfo和getnameinfo函數(shù)域名系統(tǒng)就是通常所說的DNS(DomainNameSystem)系統(tǒng),而DNS系統(tǒng)主要用于主機名與IP地址間的映射,同時還可以通過主機名或主機地址獲取主機的相關信息。那么在DNS系統(tǒng)中是怎樣實現(xiàn)主機名與IP地址間的映射的呢?答案就是通過資源記錄來實現(xiàn)。在DNS中的條目稱為資源記錄RR(ResourceRecord),它們主要有以下幾類:(1)A。A記錄將一個域名地址對應一個32bit的IPv4地址。(2)AAAA。AAAA記錄(稱為“四A”記錄)將主機名映射為128位的IPv6地址。(3)NS。NS記錄用于指定一個域名服務器,它負責定義由哪個域名服務器負責管理維護本區(qū)域的記錄。(4)MX.MX記錄用于指定一臺主機的域名,所有發(fā)送到本域的電子郵件都由這臺主機接收。(5)PTR。PTR記錄(稱為“指針記錄”)將IP地址映射為主機名。(6)CNAME。CNAME代表CanonicalName(規(guī)范名字),作用是允許主機建立別名。名字解析過程應用程序代碼解析器代碼解析器配置文件函數(shù)調(diào)用函數(shù)返回本地名字服務器其他名字服務器UDP請求UDP應答應用進程gethostbyname()函數(shù)找主機名最基本的函數(shù)gethostbyname(),該函數(shù)執(zhí)行如果成功,它返回一個指向結(jié)構(gòu)hostent的指針,該結(jié)構(gòu)中包含了該主機的所有IPv4地址或IPv6地址;如果失敗返回空指針。#include<netdb.h> structhostent*gethostbyname(constchar*hostname);參數(shù)hostname是主機的域名地址,函數(shù)將查詢的結(jié)果作為參數(shù)返回。如果失敗返回空指針;如果成功此參數(shù)返回的非空指針指向如下的hostent結(jié)構(gòu):結(jié)構(gòu)hostentstructhostent { char*h_name; /*主機的正式名稱*/ char**h_aliases; /*主機的別名列表*/ int h_addrtype; /*主機地址類型*/ int h_length;

/*主機地址長度*/ char**h_addr_list; *主機IP地址的列表*/ };#defineh_addrh_addr_list[0] /*在列表中的第一個地址*/gethostbyname返回的信息h_nameh_aliasesh_addrtypeh_lengthh_addr_listhostent{}正式主機名\0別名1\0別名2\0IP地址1IP地址2IP地址3NULLNULLAF_INETin_addr{}in_addr{}in_addr{}gethostbyname()函數(shù)是怎樣工作的原來gethostbyname函數(shù)首先在/etc/hosts文件中查找是否有匹配的主機名。如果沒有,則根據(jù)在域名解析配置文件/etc/resolv.conf中指定的本地域名服務器的地址向本地域名服務器發(fā)送地址解析請求。如果本地域名服務器能夠解析,則返回UDP數(shù)據(jù)包說明結(jié)果,否則本地域名服務器將向上一層的域名服務器發(fā)送域名解析請求。下面舉個例子來看看gethostbyname()函數(shù)#include<netinet/in.h>#include<arpa/inet.h>#include<netdb.h>

main(intargc,constchar**argv){ulong_taddr;structhostent*hp;char**p;if(argc!=2){(void)printf("usage:%shost_name\n",argv[0]);exit(1);}hp=gethostbyname(argv[1]);if(hp==NULL){(void)printf("hostinformationfor%snotfound\n",argv[1]);exit(2);}for(p=hp->h_addr_list;*p!=0;p++){structin_addrin;char**q;(void)memcpy(&in.s_addr,*p,sizeof(in.s_addr));(void)printf("%s\t%s",inet_ntoa(in),hp->h_name);for(q=hp->h_aliases;*q!=0;q++)(void)printf("%s",*q);(void)putchar('\n');}exit(0);}RES_USE_INET6解析器選項解析器選項是用來通知解析器讓gethostbyname返回的是IPv6地址而不是IPv4地址。設置該選項的方法有以下3種:(1)應用程序可以設置此選項(2)如果環(huán)境變量RES_OPTIONS中含有串inet6,則此選項打開(3)在配置文件中如果包含“optionsinet6”時選項打開,但如果這樣設置了,則此選項影響主機上調(diào)用解析器函數(shù)的所有應用程序,因此這項技術要在結(jié)構(gòu)hostent中返回的IPv6地址可以被主機上的所有應用程序處理時才能使用。gethostbyname2函數(shù)對IPv6的支持gethostbyname2()函數(shù),該函數(shù)有兩個參數(shù),并允許指定地址族。#include<netdb.h>structhostent*gethostbyname2(constchar*hostname,intfamily)返回:若為非空指針,則表示成功;若為空指針,則表示出錯,同時設置h_errno。該函數(shù)的返回值與gethostbyname的返回值相同,為一個指向結(jié)構(gòu)hostent的指針。該函數(shù)的邏輯依賴于參數(shù)family和解析器選項RES_USE_INET6反向域名解析函數(shù)gethostbyaddr()gethostbyaddr()函數(shù)的作用是可以查詢指定的IP地址對應的主機域名地址。函數(shù)的形式如下:#include<netdb.h>structhostent*gethostbyaddr(constchar*addr,size_tlen,intfamily);返回:若為非空指針,則表示成功;若為空指針,則表示出錯,同時設置h_errno。該函數(shù)同樣返回一個指向結(jié)構(gòu)hostent的指針。而在參數(shù)中,參數(shù)addr不是char*類型,而是一個真正指向含有IPv4或IPv6地址的結(jié)構(gòu)in_addr或in6_addr的指針;len是此結(jié)構(gòu)的大小,對于IPv4地址為4,對于IPv6地址為16;參數(shù)family為AF_INET或AF_INET6。main(intargc,constchar**argv){ulong_taddr;structhostent*hp;char**p;if(argc!=2){printf("usage:%sIP-address\n",argv[0]);exit(1);}if(((addr=inet_addr(argv[1]))==-1){printf("IP-addressmustbeoftheforma.b.c.d\n");exit(1);}hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);if(hp==NULL){printf("hostinformationfor%snotfound\n",argv[1]);exit(1);}for(p=hp->h_addr_list;*p!=0;p++){structin_addrin;char**q;memcpy(&in.s_addr,*p,sizeof(in.s_addr));printf("%s\t%s",inet_ntoa(in),hp->h_name);for(q=hp->h_aliases;*q!=0;q++)printf("%s",*q);}exit(0);}[root@localhosttest]#./blocalhost.localdomainlocalhost地址轉(zhuǎn)換例子#include<netdb.h>#include<stdio.h>#include<stdlib.h>#include<sys/socket.h>#include<netinet/in.h>intmain(intargc,char*argv[]){structsockaddr_inaddr;structhostent*he;char**alias;if(argc<2){printf("Usage:%sname|IP",argv[0]);exit(1);}地址轉(zhuǎn)換例子(cont.)

argv++;for(;*argv!=NULL;argv++){if(inet_aton(*argv,&addr.sin_addr)!=0){he=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);printf("addressinformationofIP%s:\n",*argv);}else{he=gethostbyname(*argv);printf("addressinformationofhost%s:\n",*argv);}if(he==NULL){printf("noaddressinformationof%s\n",*argv);continue;}地址轉(zhuǎn)換例子(cont.)

printf("Officaialhostname:%s\n",he->h_name);printf("namealiases:");for(alias=he->h_aliases;*alias!=NULL;alias++)printf("%s\n",*alias);printf("\nIPaddresses:");for(alias=he->h_addr_list;*alias!=NULL;alias++)printf("%s\n",inet_ntoa(*(structin_addr*)(*alias)));}}uname()函數(shù)該函數(shù)功能如同它的名字一樣,即返回當前主機的名字,它返回的信息比較完整。下一節(jié)將介紹返回主機名字的另一個函數(shù),但它返回的信息就相對少些。經(jīng)常與函數(shù)gethostbyname()一起用來確定本地主機的IP地址。它的具體形式如下:#include<sys/utsname.h> intuname(structutsname*name);返回:若為非負值,則表示成功;若為-1,則表示出錯。uname函數(shù)該函數(shù)返回本機的名字,它不是解析器庫中的一部分,但它經(jīng)常與gethostbyname函數(shù)一起用來確定本地主機IP地址;函數(shù)的參數(shù)是“值-結(jié)果”參數(shù),其類型如下:#defineUTS_NAMESIZE 16#defineUTS_NODESIZE 256structutsname{ charsysname[UTS_NAMESIZE]; /*nameofthisoperatingsystem*/ charnodename[UTS_NODESIZE]; /*主機的名字*/ charrelease[UTS_NAMESIZE]; /*O.S內(nèi)部版本*/ charversion[UTS_NAMESIZE]; /*O.S發(fā)行版本號*/ charmachine[UTS_NAMESIZE]; /*硬件版本*/}獲取本機IP地址#include<netdb.h>#include<sys/utsname.h>#include<netinet/in.h>#include<stdio.h>intmain(void){structhostent*he;structutsnamemyname;structin_addraddr;chartemp[100];if(uname(&myname)<0)return(0);獲取本機IP地址(續(xù))

if((he=gethostbyname(myname.nodename))==NULL){perror("error.");exit(1);}printf("OSnameis%s\n",myname.sysname);printf("nodenameis%s\n",myname.nodename);printf("OSversionreleaseis%s\n",myname.release);printf(“hardwareversionis%s\n”,myname.version);printf("hardwaretypeis%s\n",myname.machine);memcpy(&addr,he->h_addr,sizeof(addr));printf("hostIPis%s\n",inet_ntoa(addr));return(0);}gethostname函數(shù)該函數(shù)同樣返回當前主機的名字,但返回信息比上節(jié)介紹的函數(shù)少,該函數(shù)形式如下:#include<unistd.h>int gethostname(char*name,size_tnamelen);返回:若為0,則表示成功;若為-1,則表示出錯。name是指向主機名存儲位置的指針,namelen是此數(shù)組的大小。如果有空間,主機名以空字符結(jié)束。主機名的最大長度通常是由頭文件<sys/param.h>定義的常值MAXHOSTNAMELEN。#include<unistd.h>intmain(){charbuf[100];size_tnamelen;namelen=sizeof(buf);gethostname(buf,namelen);printf("hostnameis%s\n",buf);}getservbyname和getservbyport函數(shù)函數(shù)getservbyname()可以通過服務名來獲取服務器端口號,函數(shù)的形式如下:#include<netdb.h>structservent*getservbyname(constchar*servname,constchar*protoname);返回:若為非空指針,則表示成功;若為空指針,則表示出錯。函數(shù)是getservbyport()函數(shù),該函數(shù)的作用是通過端口號來獲取服務名,它是反向的查詢服務名稱,即功能與getservbyname()函數(shù)相反。下面就來看一下它的具體形式:#include<netdb.h>structservent*getservbyport(intport,constchar*protname);返回:若為非空指針,則表示成功;若為空指針,則表示出錯。獲取服務名字函數(shù)該函數(shù)根據(jù)服務器提供的服務名字獲取服務器的有關信息;在/etc/services文件中查找。參數(shù)servname指向服務的名字,如”domain”,”ftp”,”www”;函數(shù)返回的結(jié)構(gòu)如下:structservent{ char *s_name; /*officialservicename*/ char **s_aliases; /*aliaslist*/ int s_port; /*portnumber,net-byteorder*/ char *s_proto; /*protocoltouse*/}如:structservent*ptr;sptr=getservbyname(“FTP”,“TCP”);#include<netdb.h>intmain(){structservent*ptr;ptr=getservbyname("ssh",NULL);if(ptr==NULL){perror("error");exit(0);}printf("portis:%d",ntohs(ptr->s_port));}獲取服務名字函數(shù)(cont.)#include<netdb.h>structservent*getservbyport(intport,constchar*protoname);

返回:非空指針-成功;空指針-出錯。該函數(shù)根據(jù)端口號和可選的協(xié)議查找相應的服務;參數(shù)port必須為網(wǎng)絡字節(jié)序;如:structservent*sptr;sptr=getservbyport(htons(53),“UDP); /*DNSusingUDP*/sptr=getservbyport(htons(21),“TCP”); /*FTPusingTCP*/sptr=getservbyport(htons(21),NULL); /*FTPusingTCP*/sptr=getservbyport(htons(21),”UDP”); /*thiscallwillfail*/#include<netdb.h>#include<errno.h>#include<stdio.h>intmain(){structservent*srv;inti;for(i=1;i<100;i++){srv=getservbyport(htons(i),NULL);if(srv==NULL){printf("PORT%dnoservice\n",i);}elseprintf("PORT:%dservice:%s\n",i,srv->s_name);}}獲取套接字的地址信息#include<sys/socket.h>intgetsockname(intsockfd,structsockaddr*localaddr,socklen_t*len);intgetpeername(intsockfd,structsockaddr*peeraddr,socklen_t*len);

均返回:0-成功;-1-出錯getsockname函數(shù)返回套接字的本地地址;而后者返回套接字對應的遠程地址;一般在以下三中情況下調(diào)用這兩個函數(shù):客戶機在connect后,用getsockname獲取系統(tǒng)選擇的ip和端口號;以INADDR_ANY調(diào)用bind的服務器,在接收到連接后(即accept后),調(diào)用getsockname獲取系統(tǒng)選擇的IP地址;服務器獲得連接后,并exec真正的程序后。只能用getpeername獲取客戶套接字地址;getaddrinfo、gai_strerror和host_serv函數(shù)getaddrinfo()函數(shù)在庫函數(shù)中隱藏了所有協(xié)議依賴性,因此應用程序只需要處理由getaddrinfo填寫的套接口地址結(jié)構(gòu)即可。該函數(shù)的形式如下:#include<netdb.h>intgetaddrinfo(constchar*hostname,constchar*service,conststructaddrinfo*hints,structaddrinfo**result);返回:若成功返回0,若出錯返回非0。getaddrinfo函數(shù)ai_family指定了地址族,可取值如下:

AF_INET

2

IPv4

AF_INET6

23

IPv6

AF_UNSPEC

0

協(xié)議無關#ai_socktype指定套接字的類型

SOCK_STREAM

1

SOCK_DGRAM

2

數(shù)據(jù)報在AF_INET通信域中套接字類型SOCK_STREAM的默認協(xié)議是TCP(傳輸控制協(xié)議)

在AF_INET通信域中套接字類型SOCK_DGRAM的默認協(xié)議是UDP(用戶數(shù)據(jù)報協(xié)議)getaddrinfo函數(shù)ai_flags指定了如何來處理地址和名字,可取值如下:

gai_strerror()函數(shù),該函數(shù)返回的非零錯誤值的名字和含義如表6-2所示。gai_strerror()函數(shù)以這些值作為它的一個參數(shù),返回指向?qū)某鲥e信息字符串的指針。該函數(shù)形式如下:# include<netdb.h> char*gai_strerror(interror);返回:一個指向描述出錯信息字符串的指針。填寫hints結(jié)構(gòu)的函數(shù),即host_serv()函數(shù),它以地址族和套接口類型作為參數(shù),形式如下:#include"unp.h"structaddrinfo*host_serv(constchar*hostname,constchar*service,int

family,intsocktype);返回:若成功返回指向addrinfo結(jié)構(gòu)的指針,若出錯返回NULL。freeaddrinfo函數(shù)getaddrinfo()函數(shù)返回的存儲空間,包括addrinfo結(jié)構(gòu)、ai_addr結(jié)構(gòu)和ai_canonname字符串,都是用malloc動態(tài)獲取的。這些空間可調(diào)用freeadddrinfo()函數(shù)釋放。下面就來看一下這個函數(shù)。#include<netdb.H>voidfreeaddrinfo(structaddrinfo*ai);該函數(shù)的參數(shù)ai指向getaddrinfo返回的第一個addrinfo結(jié)構(gòu),因此該鏈表中的所有結(jié)構(gòu)和這些結(jié)構(gòu)所指向的動態(tài)存儲空間都將被釋放。這樣可以通過它來回收資源,同時如果在getaddrinfo()函數(shù)中調(diào)用某個操作時失敗,也可以調(diào)用freeaddrinfo()函數(shù)來對錯誤進行處理。使用getaddrinfo的TCP和UDP有了host_serv()函數(shù)后,現(xiàn)在來看一下getaddrinfo在TCP中的應用,先從tcp_connect()函數(shù)著手,該函數(shù)執(zhí)行客戶程序的一般操作步驟是:創(chuàng)建一個TCP套接口并與服務器建立連接,它的形式如下:#include"unp.h"inttcp_connect(constchar*hostname,constchar*service);返回:若成功則返回已連接套接口的描述字,若出錯則不返回。#include"unp.h"

inttcp_connect(constchar*host,constchar*serv){intsockfd,n;structaddrinfohints,*res,*ressave;bzero(&hints,sizeof(structaddrinfo));hints.ai_family=AF_UNSPEC;hints.ai_socktype=SOCK_STREAM;if((n=getaddrinfo(host,serv,&hints,&res))!=0)err_quit("tcp_connecterrorfor%s,%s:%s",host,serv,gai_strerror(n));ressave=res;do{sockfd=socket(res->ai_family,res->ai_socktype,res->ai_protocol);if(sockfd<0)continue; /*ignorethisone*/if(connect(sockfd,res->ai_addr,res->ai_addrlen)==0)break; /*success*/Close(sockfd); /*ignorethisone*/}while((res=res->ai_next)!=NULL);if(res==NULL) /*errnosetfromfinalconnect()*/err_sys("tcp_connecterrorfor%s,%s",host,serv);freeaddrinfo(ressave);return(sockfd);}當用此函數(shù)時如果getaddrinfo()失敗,或所有connect()失敗,這個函數(shù)(以及在以下描述的給getaddrinfo()提供一些簡單接口的其他函數(shù))將終止。只有在成功時這個函數(shù)才返回。接下來看一下另一個函數(shù)tcp_listen(),它是用來執(zhí)行TCP服務器程序的一般操作步驟,即創(chuàng)建一個TCP套接口,給它捆綁服務器的眾所周知端口,并允許接收外來的連接請求,該函數(shù)形式如下:#include"unp.H"inttcp_listen(constchar*hostname,constchar*service,socklen_t*lenptr);返回:若成功返回已連接套接口描述字,若出錯則不返回。#include"unp.h"

inttcp_listen(constchar*host,constchar*serv,socklen_t*addrlenp){intlistenfd,n;constinton=1;structaddrinfo hints,*res,*ressave;bzero(&hints,sizeof(structaddrinfo));hints.ai_flags=AI_PASSIVE;hints.ai_family=AF_UNSPEC;hints.ai_socktype=SOCK_STREAM;if((n=getaddrinfo(host,serv,&hints,&res))!=0)err_quit("tcp_listenerrorfor%s,%s:%s",host,serv,gai_strerror(n));ressave=res;do{listenfd=socket(res->ai_family,res->ai_socktype,res->ai_protocol);if(listenfd<0) continue; /*error,trynextone*/Setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));if(bind(listenfd,res->ai_addr,res->ai_addrlen)==0)break; /*success*/Close(listenfd); /*binderror,closeandtrynextone*/}while((res=res->ai_next)!=NULL);if(res==NULL) /*errnofromfinalsocket()orbind()*/err_sys("tcp_listenerrorfor%s,%s",host,serv);Listen(listenfd,LISTENQ);if(addrlenp)*addrlenp=res->ai_addrlen; /*returnsizeofprotocoladdress*/freeaddrinfo(ressave);return(listenfd);}到現(xiàn)在為止,已用以上兩個函數(shù)的源碼介紹了getaddrinfo()函數(shù)在TCP中的一些應用,這將對理解getaddrinfo()函數(shù)有很大的幫助,但是這是在TCP中的應用,那么在UDP中又是怎樣的情況呢?同樣分別通過udp_client()、udp_connect()、udp_server()三個函數(shù)來解答這個問題。因為提供了一個創(chuàng)建未連接UDP套接口的客戶函數(shù)給getaddrinfo(),所以在UDP中getaddrinfo()函數(shù)的應用有所改變。而另一個函數(shù)udp_connect()則提供一個創(chuàng)建已連接UDP的套接口。首先來看一下udp_client()函數(shù),該函數(shù)的作用是創(chuàng)建一個未連接UDP套接口,返回3項數(shù)據(jù):第一,返回值是套接口描述字;第二,saptr是一個指向套接口地址結(jié)構(gòu)(由udp_client動態(tài)分配)的指針(由調(diào)用者聲明)的地址,在這個結(jié)構(gòu)中存放目的IP地址和端口號,用來調(diào)用sendto(),套接口地址結(jié)構(gòu)的大小在1enp指向的變量中返回;最后一個參數(shù)不能是空指針(tcp_listen的最后一個參數(shù)是允許的),因為套接口地址結(jié)構(gòu)的長度在調(diào)用函數(shù)sendto()和recvfrom()時都是需要的,該函數(shù)的形式如下:#include"unp.h"intudp_client(constchar*hostname,constchar*service,void**saptr,

socklen_t*lenp);返回:若成功返回未連接套接口的描述字,若出錯則不返回。#include"unp.h"

intudp_client(constchar*host,constchar*serv,void**saptr,socklen_t*lenp){intsockfd,n;structaddrinfo hints,*res,*ressave;bzero(&hints,sizeof(structaddrinfo));hints.ai_family=AF_UNSPEC;hints.ai_socktype=SOCK_DGRAM;if((n=getaddrinfo(host,serv,&hints,&res))!=0)err_quit("udp_clienterrorfor%s,%s:%s",host,serv,gai_strerror(n));ressave=res;do{sockfd=socket(res->ai_family,res->ai_socktype,res->ai_protocol);f(sockfd>=0)break; /*success*/}while((res=res->ai_next)!=NULL);if(res==NULL) /*errnosetfromfinalsocket()*/err_sys("udp_clienterrorfor%s,%s",host,serv);*saptr=Malloc(res->ai_addrlen);memcpy(*saptr,res->ai_addr,res->ai_addrlen);*lenp=res->ai_addrlen;freeaddrinfo(ressave);return(sockfd);}接下來看一下udp_connect()函數(shù),該函數(shù)創(chuàng)建一個已連接UDP套接口,該函數(shù)形式如下:#include"unp.h"intudp_connect(constchar*hostname,constchar*service);返回:如果成功則返回套接口描述字,若出錯則不返回。當?shù)玫揭堰B接UDP套接口后,在udp_client()函數(shù)中所需的后兩個參數(shù)就不再需要了。用戶可以用write函數(shù)代替sendto函數(shù),于是就不再需要返回套接口地址結(jié)構(gòu)和它的長度了。

intudp_connect(constchar*host,constchar*serv){intsockfd,n;structaddrinfohints,*res,*ressave;bzero(&hints,sizeof(structaddrinfo));hints.ai_family=AF_UNSPEC;hints.ai_socktype=SOCK_DGRAM;if((n=getaddrinfo(host,serv,&hints,&res))!=0)err_quit("udp_connecterrorfor%s,%s:%s",host,serv,gai_strerror(n));ressave=res;do{sockfd=socket(res->ai_family,res->ai_socktype,res->ai_protocol);if(sockfd<0)continue; /*ignorethisone*/if(connect(sockfd,res->ai_addr,res->ai_addrlen)==0)break; /*success*/Close(sockfd); /*ignorethisone*/}while((res=res->ai_next)!=NULL);if(r

溫馨提示

  • 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論