网络工程课程设计-PING程序设计与FTP设计.doc_第1页
网络工程课程设计-PING程序设计与FTP设计.doc_第2页
网络工程课程设计-PING程序设计与FTP设计.doc_第3页
网络工程课程设计-PING程序设计与FTP设计.doc_第4页
网络工程课程设计-PING程序设计与FTP设计.doc_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 课课 程程 设设 计计 课程名称_网络工程课程设计 题目名称_ping 程序设计 题目名称 文件传输协议的简单设计 题目名称 数据链路层协议的设计 学生学院_ _ 专业班级_网络工程 学 号_ 学生姓名_ _ 指导教师_ _ 2009 年 12 月 25 日 2 pingping 目录目录 1 1 具体设计任务具体设计任务33 1 11 1 实验目的实验目的33 12 实验内容和要求实验内容和要求3.3 121 实验内容实验内容33 122 具体要求具体要求3 1. 3 实验主要仪器设备和材料实验主要仪器设备和材料44 2 工作原理及设计方案工作原理及设计方案44 2.12.1 pingping 的工作原理的工作原理.4.4 2.22.2 原理框图原理框图55 3 3 主要代码及其功能主要代码及其功能66 4 4 结果分析结果分析.10.10 5 思考题思考题.11.11 6 心得体会心得体会1212 3 课程设计一:课程设计一:pingping 程序设计程序设计 1 设计任务目的及要求设计任务目的及要求 1.1 设计目的 ping 程序是我们使用的比较多的用于测试网络连通性的程序。ping 程序基 于 icmp,使用 icmp 的回送请求和回送应答来工作。由计算机网络课程知道, icmp 是基于 ip 的一个协议,icmp 包通过 ip 的封装之后传递。 课程设计中选取 ping 程序的设计,其目的是希望同学们通过 ping 程序的 设计,能初步掌握 tcp/ip 网络协议的基本实现方法,对网络的实现机制有进一 步的认识。 1.2 设计要求设计要求 1、raw 模式的 socket 编程 ping 程序是面向用户的应用程序,该程序使用 icmp 的封装机制,通过 ip 协议来工作。为了实现直接对 ip 和 icmp 包进行操作,实验中使用 raw 模式的 socket 编程。 熟悉 socket 的编程,包括基本的系统调用如 socket、bind 等; 2、具体内容 1) 定义数据结构 需要定义好 ip 数据报、icmp 包等相关的数据结构; 2) 程序实现 在 windows 环境下实现 ping 程序; 3) 程序要求 在命令提示符下输入: ping . 其中 为目的主机的 ip 地址,不要求支持域名,对是否带有开关变 量也不做要求。不带开关变量时,要求返回 4 次响应。 返回信息的格式: reply from . 或 4 request timeout (无法 ping 通的情况) 。 1.31.3 实验环境实验环境 pc 机一台(可以与其他机联通或者可以上网) 操作系统为 windows xp 软件为 vc6.0 windows 环境下 2工作原理工作原理及设计方案及设计方案 2.1 pingping 的工作原理的工作原理 ping 程序是用来探测主机到主机之间是否可通信,如果不能 ping 到某台 主机,表明不能和这台主机建立连接。ping 使用的是 icmp 协议,它发送 icmp 回送请求消息给目的主机。icmp 协议规定:目的主机必须返回 icmp 回送应答 消息给源主机。如果源主机在一定时间内收到应答,则认为主机可达。 icmp 协议通过 ip 协议发送的,ip 协议是一种无连接的,不可靠的数据包 协议。因此,保证数据送达的工作应该由其他的模块来完成。其中一个重要的 模块就是 icmp(网络控制报文)协议。 当传送 ip 数据包发生错误比如主机不可达,路由不可达等等,icmp 协议将会把错误信息封包,然后传送回给主机。给主机一个处理错误的机会, 这也就是为什么说建立在 ip 层以上的协议是可能做到安全的原因。icmp 数据 包由 8bit 的错误类型和 8bit 的代码和 16bit 的校验和组成。而前 16bit 就组 成了 icmp 所要传递的信息。 ping 利用 icmp 协议包来侦测另一个主机是否可达。原理是用类型码为 0 的 icmp 发请求,受到请求的主机则用类型码为 8 的 icmp 回应。ping 程序来计 算间隔时间,并计算有多少个包被送达。用户就可以判断网络大致的情况。 2.2 原理框图 5 开始 发送数据包? 接收数据包? 解析数据包? 结束 输出失败信息结束函数 输出失败信息结束函数 创建套接字 判断是不是无限? 输入域名、大小和次数 解析域名 填写 icmp 数据包? 计算校验和 输出失败信息结束函数 . .3 3 程序源代码程序源代码 否 是 是 是 否 否 否 是 是 输出失败信息结束程序 3 否 6 icmpicmp 头结构头结构 typedef struct icmphdr byte i_type; / 数据的类型 byte i_code; / subcode 类型 ushort i_cksum; / 校验和 ushort i_id; / id ushort i_seq; / 序号 ulong timestamp; icmpheader; ipip 头结构头结构 typedef struct iphdr unsigned int h_len:4; /长度 unsigned int version:4; / 版本 unsigned char tos; / 服务类型 unsigned short total_len; / 实际长度 unsigned short ident; / 标识 unsigned short frag_and_flags; /标志 unsigned char ttl; /生存时间 unsigned char proto; /协议(tcp, udp etc) unsigned short checksum; / ip 校验 unsigned int sourceip; unsigned int destip; ipheader; 填写填写 icmpicmp 数据包数据包* * void fill_icmp_data(char * icmp_data, int datasize)/填 充 icmp icmpheader *icmp_hdr; char *datapart; icmp_hdr = (icmpheader*)icmp_data; icmp_hdr-i_type = icmp_echo; icmp_hdr-i_code = 0; icmp_hdr-i_id=(ushort)getcurrentprocessid() icmp_hdr-i_cksum = 0; icmp_hdr-i_seq = 0; datapart = icmp_data + sizeof(icmpheader); /数据 段地址 memset(datapart,0,datasize - sizeof(icmpheader); 计算校验和计算校验和 ushort checksum(ushort *buffer, int size)/求校 验和 unsigned long cksum=0; while(size 1) cksum+=*buffer+; size -=sizeof(ushort); if(size) cksum += *(uchar*)buffer; cksum = (cksum 16) + (cksum cksum += (cksum 16); return (ushort)(cksum); 7 数据包解码数据包解码 int decode_resp(char *buf, int bytes,struct sockaddr_in*from,unsignedlong icmpheader *icmphdr; unsigned short iphdrlen; /ip 头的长度 cstring str,str1,str2; iphdr = (ipheader *)buf; iphdrlen = (iphdr-h_len) * 4 ; if (bytes sin_addr); info-addstring(“too few bytes from “ + str1); info-postmessage(wm_vscroll, sb_bottom, 0); /str.format(); icmphdr = (icmpheader*)(buf + iphdrlen); if (icmphdr-i_type != icmp_echoreply) str1.format(“%d“,icmphdr-i_type); info-addstring(“non-echo type “+ str1 + “recvd“ ); info-postmessage(wm_vscroll, sb_bottom, 0); return 1; if(icmphdr-i_id!=(ushort)getcurrentprocessid() info-addstring(“someone elses packet!“); info-postmessage(wm_vscroll, sb_bottom, 0); return 1; int k = (int)iphdr-ttl; cstring ttl; ttl.format(“%d“,k); str.format(“%d“,(int) bytes); str1.format(“%d“,icmphdr-i_seq); str2.format(“%d“,arrivetime-icmphdr-timestamp); info-addstring(str + “ bytes from“ + “ : “ + inet_ntoa(from-sin_addr)+ “ icmp_seq = “ + str1 + . + “ time: “ + str2 + “ ms. “ + “ttl “ + ttl); info-postmessage(wm_vscroll, sb_bottom, 0); sleep(1000); return 0; 8 if(bag-select = 1) bag-ipctrl-getaddress( addr ); addr = (dword)htonl(unsigned long)addr); dest.sin_addr = *( in_addr * ) hp = gethostbyaddr(char*) if (hp != null) (bag-dnsctrl)-setsel(0,-1,false); (bag-dnsctrl)-replacesel(hp-h_name); if (!hp) bag-infolist-addstring(“unable to resolve “ + str); return 0; /初始化 dest if (hp) dest.sin_family = hp-h_addrtype; else dest.sin_family = af_inet; /获取 ip 或域名,并显示 dest_ip = inet_ntoa(dest.sin_addr); /将网络地址转换成“.”点隔的字符串格式 times=def_packet_number; datasize = def_packet_size; datasize += sizeof(icmpheader); /数据段的大小 icmp_data = (char*)xmalloc(max_packet); /为 icmp 分配内存 recvbuf = (char*)xmalloc(max_packet); if (!icmp_data) str.format(“%d“,getlasterror(); bag-infolist-addstring(“heapalloc failed “+ str); return 0; . 9 while(true) /ping 4 次 for(int i=0;ii_cksum = 0; (icmpheader*)icmp_data)-timestamp= gettickcount(); /获取发送时间 (icmpheader*)icmp_data)-i_seq = seq_no+; (icmpheader*)icmp_data)-i_cksum= checksum(ushort*)icmp_data,datasize); /求校验和 bwrote=sendto(sockraw,icmp_data,datasize,0,(stru ct sockaddr*) /发送 if (bwrote = socket_error) if (wsagetlasterror() = wsaetimedout) bag-infolist-addstring(“request timed out.“); bag-infolist-postmessage(wm_vscroll, sb_bottom, 0); continue; str.format(“%d“,wsagetlasterror(); bag-infolist-addstring(“sendto failed: “ + str); return 0; if (bwrote infolist-addstring(“wrote“ + str + “ bytes“); bread=recvfrom(sockraw,recvbuf,max_packet ,0,(struct sockaddr*) /接收 arrivetime = gettickcount(); /获取接收时间 if (bread = socket_error) if (wsagetlasterror() = wsaetimedout) bag-infolist-addstring(“request timed out.“); bag-infolist-postmessage(wm_vscroll, sb_bottom, 0); continue; str.format(“%d“,wsagetlasterror(); bag-infolist-addstring(“recvfrom failed: “ + str); return 0; if(!decode_resp(recvbuf,bread, /* 成功接收的数目+ */ /sleep(1000); if(!bag-t) /等于复选按钮的值,为真就做-t,无限循 环 ping break; /* 显示统计结果 */ str = dest_ip; bag-infolist-addstring(“ping statistics for “ + str); cstring str1,str2; str.format(“%d“,statistic); str1.format(“%d“,times-statistic); str2.format(“%f“,(float)(times- statistic)/times*100); bag-infolist-addstring(“ packets: sent = 4,received = “ + str + “, lost = “ + str1 + + str2+“% loss“); bag-infolist-addstring(“); wsacleanup(); return 0; 10 测试步骤及实验结果 首先,运行程序,使用默认 ip(本机 ip)ping: 接着,选择域名,并输入 ,默认 ping 次数为 4 次,在 ip 地址栏可以显示相 应的 ip 地址: 11 : 最后,我们将“-t”选中,连续循环“ping”: 结论 本程序能全部完成课程设计的要求功能,能域名解析,ping 服务器,并能实现-t 参数 无限循环 ping。 界面比较友好,显示、按键等均正常,并有“停止重 ping” 、 “退出”按键,能较好 与用户交互。 缺点是程序不稳定,不能很好应付网络状况不明朗的情况。 5 思考题思考题 1. 本题目只要求实现 ping 的一些简单功能,在 windows 命令行模式下,输入 “ping”回车,查看 ping 的所有功能,考虑如何实现这些功能。 答:首先,ping 命令会构建一个固定格式的 icmp 请求数据包,然后由 icmp 协 议将这个数据包连同地址“”一起交给 ip 层协议(和 icmp 一样, 实际上是一组后台运行的进程),ip 层协议将以地址“”作为目 的地址,本机 ip 地址作为源地址,加上一些其他的控制信息,构建一个 ip 数 12 据包,并在一个映射表中查找出 ip 地址 所对应的物理地址(也叫 mac 地址,熟悉网卡配置的朋友不会陌生,这是数据链路层协议构建数据链路 层的传输单元帧所必需的),一并交给数据链路层。后者构建一个数据帧, 目的地址是 ip 层传过来的物理地址,源地址则是本机的物理地址,还要附加上 一些控制信息,依据以太网的介质访问规则,将它们传送出去。 2. 如果一台主机能 ping 通自己但网络不通,可能是什么原因? 答:(1)可能计算机的网卡安装不正确,也可能是没连通;(2)计算机的 tcp/ip 协议没有与网卡有效的绑定;(3)windows 服务器的网络服务功能还没 启动 3. 考虑 netstat、traceroute、ipconfig 等网络测试应用程序的工作原理以 及使用。 答:netstat 的工作原理及使用:(1)显示本地或与之相连的远程机器的连 接状态,包括 tcp、ip、udp、icmp 协议的使用情况,了解本地机开放的端口情 况.(2)检查网络接口是否已正确安装,如果在用 netstat 这个命令后仍不能显 示某些网络接口的信息,则说明这个网络接口没有正确连接,需要重新查找原 因。(3)通过加入“-r”参数查询与本机相连的路由器地址分配情况。(4)检查 一些常见的木马等黑客程序,因为任何黑客程序都需要通过打开一个端口来达 到与其服务器进行通信的目的。 traceroute 程序的设计是利用 icmp 及 ip header 的 ttl(time to live) 。 首先,traceroute 送出一个 ttl 是 1 的 ip 数据报到目的地,当路径上的第一 个路由器(router)收到这个数据报时,它将 ttl 减 1。此时,ttl 变为 0 了, 所以该路由器会将此数据报丢掉,并送回一个icmp time exceeded消息, traceroute 收到这个消息后,便知道这个路由器存在于这个路径上,接着 traceroute 再送出另一个 ttl 是 2 的 datagram,发现第 2 个路由器 traceroute 每次将送出的数据报的 ttl 加 1 来发现另一个路由器,这个重复 的动作一直持续到某个数据报抵达目的地。当数据报到达目的地后,该主机并 不会送回 icmp time exceeded 消息,因为它已是目的地了。 ipconfig 的工作原理及使用: (1)查找目标主机的 ip 地址及其它有关 tcp/ip 协议的信息。(2)当用户的网络中设置的是 dhcp(动态 ip 地址配置协议) 13 时,利用 ipconfig/winipcfg 可以让用户很方便地了解到所用 ipconfig/winipcfg 机的 ip 地址的实际配置情况。因为它有一个“/all”这个 参数,所以它可侦查到本机上所有网络适配的 ip 地址分配情况,比 ping 命令 更为详细。如果我们一台 ip 地址为 99 上运行”ipconfig”命令后, 窗口中显示了主机名、dns 服务器、节点类型以及主机的相关信息如网卡类型、 mac 地址、ip 地址、子网掩码以及默认网关等。其中网络适配器的 mac 地址在 检测网络错误时非常有用。 配置不正确的 ip 地址或子网掩码是接口配置的常 见故障。其中配置不正确的 ip 地址有两种情情况: (1)网号部分不正确。此时 执行每一条 ipconfig 命令都会显示“no answer” ,这样,执行该命令后错误的 ip 地址就能被发现,修改即可。(2)主机部分不正确。如与另一主机配置的地 址相同而引起冲突。这种故障是当两台主机同时配置相同的 ip 地址时出现的间 歇性的通信问题。更换 ip 地址中的主机号部分,该问题即能排除。 6 心得体会心得体会 通过仔细阅读程序代码,查找相关资料,我大概弄懂了程序的基本过程。 程序通过发送一个 icmp 回显请求报文到目的地主机,如果有 ip 选项途中的主 机通过报文记录各自的 ip 地址,目的地主机回发一个回显应答报文,然后发送 主机通过解析回显应答报文,查看通过路由地址,并计算发送回收报文所用的 传送时间,以确定回显报文是否超时。 在学习的过程中发现程序良好的算法和优良的编程思想的同时我也发现很 多是我没见过的函数例如 wsastartup(makeword(2, 2), if(createsocket()=-1) afxmessagebox(“创建套接字失败! “); if(connectprocess()=-1) afxmessagebox(“连接失败!“); /连接监听,判断用户命令,调用相关函数 dword cnetserverdlg:connectprocess() addrlen=sizeof(sockaddr_in); if(listen(sock,3)0) fwrite(rbuff,sizeof(char),count,fd);/写入本地 fclose(fd); closesocket(sock1); /for 2 /for 1 22 3.1.2 执行命令及调用的函数 /逐级寻找目录 int cnetserverdlg:sendfilelist(socket datatcps) handle hff; win32_find_data fd; /搜索文件 hff=findfirstfile(“*“,/该函数到一个文 件夹(包括子文件夹)去搜索指定文件 if(hff=invalid_handle_value)/发生 错误-如果调用成功返回一个非 0 值 const char *errstr=“cant list files!n“; if(send(datatcps,errstr,strlen(errstr),0)=socke t_error) afxmessagebox(“传送失败!“); closesocket(datatcps); return 0; bool fmorefiles=true; while(fmorefiles) /发送此项文件信息 if(!sendfilerecord(datatcps, return 0; /搜索下一个文件 fmorefiles=findnextfile(hff,/继续查找 findfirstfile 函数搜索后的文件 closesocket(datatcps); return 1; /建目录信息格式化发送 int cnetserverdlg:sendfilerecord(socket datatcps,win32_find_data *pfd) /ftp 初始化,创建一个侦听套接字, win32_find_data 文件的全部属性信息 char n=*; char buffer1024; char filerecordmax_path+32; filetime ft; filetimetolocalfiletime( /将 utc 文件时间转换成本地文件时间 systemtime lastwtime; filetimetosystemtime( /根据一个 filetime 结构的内容,装载一个 systemtime 结构 char*dir=pfd- dwfileattributes sprintf(filerecord,“%-20s %10d %04d- %02d-%02d %02d:%02dn “, /%5s pfd-cfilename,/ 文件名 pfd-nfilesizelow, /nfilesizelow; 文 件长度低 32 位 lastwtime.wyear, lastwtime.wmonth, lastwtime.wday, lastwtime.whour, lastwtime.wminute ); if(send(datatcps,filerecord,strlen(filerecord),0) =socket_error) afxmessagebox(“传送列表出错“); return 0; recv(datatcps,buffer,1024,0); return 1; 23 /提取远方路径 int cnetserverdlg:pwd(socket datatcps) system(“cd tmp.txt“);/调用系统命令 file *fin; fin=fopen(“tmp.txt“,“r+“);/获取路径 char temp_buffer160; while (fgets(temp_buffer,80,fin)!=null) temp_bufferstrlen(temp_buffer)- 1=0; /目录判定 if(filename0!=0) sprintf(sbuff,“%s%s“,temp_buffer,filename ); else sprintf(sbuff,“%s“,temp_buffer); send(datatcps, sbuff, strlen(sbuff), 0); /格式发送 fclose(fin); system(“del tmp.txt“); closesocket(datatcps); return 0; /发送文件函数 int cnetserverdlg:sendfile(socket datatcps,file* file) for(;) /从文件中循环读取数据并发送客户端 int r=fread(sbuff,1,1024,file);/从一个流中 读数据 if(send(datatcps,sbuff,r,0)=socket_err or) afxmessagebox(“断开连接!“); /失去与客户 端的连接 closesocket(datatcps); return 0; if(r0) fwrite(rbuff,sizeof(char),count,fd); /调用 fwrite 写内容到流中,rbuff 地址的数据- fd 文件指针的目录 fclose(fd); /关闭一个流 afxmessagebox(“下载完成!“); /get 26 3.2.3 客户端上传代码 void cnetftpdlg:onput() . browseinfo binfo; zeromemory(/置零 binfo.hwndowner = this-m_hwnd; lpitemidlist lpdlist; /用来保存返回信息 binfo.lpsztitle = “请选择要共享的文件夹: “; binfo.ulflags=bif_browseincludefiles; lpdlist = shbrowseforfolder( /显示选择对话框 if(lpdlist != null) /用户按了确定按钮 tchar chpath255; shgetpathfromidlist(lpdlist, chpath);/把 项目标识列表转化成字符 strcpy(messge2,chpath); else return; strcat(order,messge1); strcat(order,“ “); strcat(order,messge2); sprintf(buff,order);/将 order 输出到 buff 里 tcpsend(buff);/调用发送命令 recv(sock,rbuff,1024,0); if(strncmp(rbuff,“put“,3)=0) strcpy(filename,rbuff+9); fd2=fopen(filename,“rb“);/rb 只允许读数据 if(fd2) if(!sendfile(sock,fd2)/调用发送文件函数 afxmessagebox(“上传失败!“); fclose(fd2); /put /发送文件函数 int cnetftpdlg:sendfile(socket datatcps,file* file) for(;)/从文件中循环读取数据并发送客户端 int r=fread(sbuff,1,1024,file);/参数:用于接收数 据的地址(指针) (ptr) ;单个元素的大小 (size) ;元素个数(nitems) ;提供数据的文件 指针(stream)返回值:成功读取的元素个数 if(send(datatcps,sbuff,r,0)=socket_error) afxmessagebox(“失去连接!“); closesocket(datatcps); return 0; if(rsendframe( t ) ) /接收方成功接收一个帧 if ( reciever-recieveframe( t ) ) /发送方接收一个确认 sender-recieveack( ); return true; return false; /*函数名:do 功 能:执行程序需要功能*/ bool do( ) cout sendersize senderwindowsize; /初始化出错帧序号数组 cout wrongsize; int *wrong= new intwrongsize + 1; *(wrong + wrongsize)= 0; if ( wrongsize ) cout *(wrong + i); /建立传输系统 gobackn *go_back_n= new gobackn( sendersize, senderwindowsize, wrong ); delete wrong; /开始传输 system( “pause“ ); system( “cls“ ); cout finished( ); ) go_back_n-transferframe( ); /传输完毕,关闭程序 cout inputcontinue; system( “cls“ ); if ( inputcontinue = y | inputcontinue = y ) return true; return false; 2.选择重发: 39 /简化帧 struct frame int sequence;/帧序号 bool checksum;/校验和,“true“代表正常 ; /简化确认或重传要求帧 struct ack_nak int sequence;/帧序号 bool flag;/标志,“true“代表这个是确认 ; selectrepeat:selectrepeat( int amount, int senderwindowsize, int *wrong, int recieverwindowsize ) /初始化信道延时,用填充帧序号为负数实现 for ( int i= 0; i enterqueue( t ); ack_nak s; s.sequence= -1; ack_nakchannel-enterqueue( s ); /* 函数名:selectrepeat:transfer 参数表: 功 能:循环传输帧、确认或者重传要求,直 到发送方所有帧都得到确认为止 */ void selectrepeat:transfer( ) for ( ; !sender-finished( ); ) selectrepeat:senderdo( ); selectrepeat:recieverdo( ); /* 函数名:selectrepeat:senderdo 参数表: 功 能:如果信道不满,发送方发送一个帧; 如果有确认或重传要求,发送方接收一个确认 或重传要求 */ void selectrepeat:senderdo( ) /发送帧 frame t; if ( !sender-sendframe( t ) ) t.sequence= -1; channel-enterqueue( t ); /取确认或者重传要求 ack_nak s; ack_nakchannel-quitqueue( s ); sender-recieveack_nak( s ); 40 /* 函数名:selectrepeat:recieverdo 参数表: 功 能:如果信道不空,接收方接收一个帧; 如果确认或重传要求的信道不满,接收方发送 一个确认或重传要求 */ void selectrepeat:recieverdo( ) /接收帧 frame t; channel-quitqueue( t ); ack_nak s; switch ( reciever-recieveframe( t ) ) /按顺序接收帧,返回确认 case 1: reciever-sendack( s ); break; /帧检验错误或者缓存满,返回重传要求 case 0: reciever-sendnak( s ); break; /由于之前有丢帧,返回填充帧用于延时 case -1: s.sequence= -1; break; default: break; ack_nakchannel-enterqueue( s ); /* 函数名:do 参数表: 功 能:执行程序需要功能 */ bool do( ) cout sendersize senderwindowsizerecieverwindowsize; /初始化出错帧序号数组 cout *wrong; system( “pause“ ); system( “cls“ ); /建立传输系统,开始传输 selectrepeat *select_repeat= new selectrepeat( sendersize, senderwindowsize, wrong,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论