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

下载本文档

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

文档简介

1、1 核准通过,归档资料。 未经允许,请勿外传! 课课 程程 设设 计计 课程名称_网络工程课程设计 题目名称_ping 程序设计 题目名称 文件传输协议的简单设计 题目名称 数据链路层协议的设计 学生学院_ _ 9jwkffwvg#tym*jg / 数据的类型 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;

2、/长度 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; iphea

3、der; 填写填写 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; d

4、atapart = 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 ck

5、sum += (cksum 16); return (ushort)(cksum); 9 数据包解码数据包解码 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(

6、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; i

7、f(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); i

8、nfo-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; 10 if(bag-select = 1) bag-ipctrl-getaddress( addr ); addr = (dword)htonl(unsigned long)addr); dest.sin_addr = *(

9、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 =

10、 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

11、(heapalloc failed + str); return 0; . 11 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,da

12、tasize,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 (bwr

13、ote 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_bo

14、ttom, 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); cstr

15、ing 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; 12 测试步骤及实验结果 首先,运行程序,使用默认 ip

16、(本机 ip)ping: 接着,选择域名,并输入 ,默认 ping 次数为 4 次,在 ip 地址栏可以显示相 应的 ip 地址: 13 : 最后,我们将“-t”选中,连续循环“ping”: 结论 本程序能全部完成课程设计的要求功能,能域名解析,ping 服务器,并能实现-t 参数 无限循环 ping。 界面比较友好,显示、按键等均正常,并有“停止重 ping” 、 “退出”按键,能较好 与用户交互。 缺点是程序不稳定,不能很好应付网络状况不明朗的情况。 5 思考题思考题 1. 本题目只要求实现 ping 的一些简单功能,在 windows 命令行模式下,输入 “ping”回车,查看 ping

17、 的所有功能,考虑如何实现这些功能。 答:首先,ping 命令会构建一个固定格式的 icmp 请求数据包,然后由 icmp 协 议将这个数据包连同地址“”一起交给 ip 层协议(和 icmp 一样, 实际上是一组后台运行的进程),ip 层协议将以地址“”作为目 的地址,本机 ip 地址作为源地址,加上一些其他的控制信息,构建一个 ip 数 14 据包,并在一个映射表中查找出 ip 地址 所对应的物理地址(也叫 mac 地址,熟悉网卡配置的朋友不会陌生,这是数据链路层协议构建数据链路 层的传输单元帧所必需的),一并交给数据链路层

18、。后者构建一个数据帧, 目的地址是 ip 层传过来的物理地址,源地址则是本机的物理地址,还要附加上 一些控制信息,依据以太网的介质访问规则,将它们传送出去。 2. 如果一台主机能 ping 通自己但网络不通,可能是什么原因? 答:(1)可能计算机的网卡安装不正确,也可能是没连通;(2)计算机的 tcp/ip 协议没有与网卡有效的绑定;(3)windows 服务器的网络服务功能还没 启动 3. 考虑 netstat、traceroute、ipconfig 等网络测试应用程序的工作原理以 及使用。 答:netstat 的工作原理及使用:(1)显示本地或与之相连的远程机器的连 接状态,包括 tcp、

19、ip、udp、icmp 协议的使用情况,了解本地机开放的端口情 况.(2)检查网络接口是否已正确安装,如果在用 netstat 这个命令后仍不能显 示某些网络接口的信息,则说明这个网络接口没有正确连接,需要重新查找原 因。(3)通过加入“-r”参数查询与本机相连的路由器地址分配情况。(4)检查 一些常见的木马等黑客程序,因为任何黑客程序都需要通过打开一个端口来达 到与其服务器进行通信的目的。 traceroute 程序的设计是利用 icmp 及 ip header 的 ttl(time to live) 。 首先,traceroute 送出一个 ttl 是 1 的 ip 数据报到目的地,当路径

20、上的第一 个路由器(router)收到这个数据报时,它将 ttl 减 1。此时,ttl 变为 0 了, 所以该路由器会将此数据报丢掉,并送回一个icmp time exceeded消息, traceroute 收到这个消息后,便知道这个路由器存在于这个路径上,接着 traceroute 再送出另一个 ttl 是 2 的 datagram,发现第 2 个路由器. traceroute 每次将送出的数据报的 ttl 加 1 来发现另一个路由器,这个重复 的动作一直持续到某个数据报抵达目的地。当数据报到达目的地后,该主机并 不会送回 icmp time exceeded 消息,因为它已是目的地了。

21、ipconfig 的工作原理及使用: (1)查找目标主机的 ip 地址及其它有关 tcp/ip 协议的信息。(2)当用户的网络中设置的是 dhcp(动态 ip 地址配置协议) 15 时,利用 ipconfig/winipcfg 可以让用户很方便地了解到所用 ipconfig/winipcfg 机的 ip 地址的实际配置情况。因为它有一个“/all”这个 参数,所以它可侦查到本机上所有网络适配的 ip 地址分配情况,比 ping 命令 更为详细。如果我们一台 ip 地址为 99 上运行”ipconfig”命令后, 窗口中显示了主机名、dns 服务器、节点类型以及主机的相关信

22、息如网卡类型、 mac 地址、ip 地址、子网掩码以及默认网关等。其中网络适配器的 mac 地址在 检测网络错误时非常有用。 配置不正确的 ip 地址或子网掩码是接口配置的常 见故障。其中配置不正确的 ip 地址有两种情情况: (1)网号部分不正确。此时 执行每一条 ipconfig 命令都会显示“no answer” ,这样,执行该命令后错误的 ip 地址就能被发现,修改即可。(2)主机部分不正确。如与另一主机配置的地 址相同而引起冲突。这种故障是当两台主机同时配置相同的 ip 地址时出现的间 歇性的通信问题。更换 ip 地址中的主机号部分,该问题即能排除。 6 心得体会心得体会 通过仔细阅

23、读程序代码,查找相关资料,我大概弄懂了程序的基本过程。 程序通过发送一个 icmp 回显请求报文到目的地主机,如果有 ip 选项途中的主 机通过报文记录各自的 ip 地址,目的地主机回发一个回显应答报文,然后发送 主机通过解析回显应答报文,查看通过路由地址,并计算发送回收报文所用的 传送时间,以确定回显报文是否超时。 在学习的过程中发现程序良好的算法和优良的编程思想的同时我也发现很 多是我没见过的函数例如 wsastartup(makeword(2, 2), if(createsocket()=-1) afxmessagebox(创建套接字失败! ); if(connectprocess()=

24、-1) afxmessagebox(连接失败!); /连接监听,判断用户命令,调用相关函数 dword cnetserverdlg:connectprocess() addrlen=sizeof(sockaddr_in); if(listen(sock,3)0) /调用 listen 来侦听客户的连接请求 afxmessagebox(侦听失败!); return(-1); for(;)/accept ()用来接受参数 s 的 socket 连线 sock1=accept(sock,(struct sockaddr far *) for(;) memset(rbuff,0,1024); mems

25、et(sbuff,0,1024); if(recv(sock1,rbuff,1024,0)0) fwrite(rbuff,sizeof(char),count,fd);/写入本地 fclose(fd); closesocket(sock1); /for 2 /for 1 24 3.1.2 执行命令及调用的函数 /逐级寻找目录 int cnetserverdlg:sendfilelist(socket datatcps) handle hff; win32_find_data fd; /搜索文件 hff=findfirstfile(*,/该函数到一个文 件夹(包括子文件夹)去搜索指定文件 if(

26、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; /搜索下一个文件 fmor

27、efiles=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; filetimetolocalfi

28、letime( /将 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.

29、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; 25 /提取远方路径 int cnetserverdlg:pwd(socket datatcps) system(cd tmp.txt);/调用系统命令 file *fin; fin=fopen(tm

30、p.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); clo

31、sesocket(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(cha

32、r),count,fd); /调用 fwrite 写内容到流中,rbuff 地址的数据- fd 文件指针的目录 fclose(fd); /关闭一个流 afxmessagebox(下载完成!); /get 28 3.2.3 客户端上传代码 void cnetftpdlg:onput() . browseinfo binfo; zeromemory(/置零 binfo.hwndowner = this-m_hwnd; lpitemidlist lpdlist; /用来保存返回信息 binfo.lpsztitle = 请选择要共享的文件夹: ; binfo.ulflags=bif_browseinc

33、ludefiles; 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

34、);/调用发送命令 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(sb

35、uff,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( )

36、; return true; return false; /*函数名:do 功 能:执行程序需要功能*/ bool do( ) cout sendersize senderwindowsize; /初始化出错帧序号数组 cout wrongsize; int *wrong= new intwrongsize + 1; *(wrong + wrongsize)= 0; if ( wrongsize ) cout n 输入出错帧序号:; for ( int i= 0; i *(wrong + i); /建立传输系统 gobackn *go_back_n= new gobackn( sendersi

37、ze, senderwindowsize, wrong ); delete wrong; /开始传输 system( pause ); system( cls ); cout finished( ); ) go_back_n-transferframe( ); /传输完毕,关闭程序 cout n 传输完毕。 endl; delete go_back_n; cout inputcontinue; system( cls ); if ( inputcontinue = y | inputcontinue = y ) return true; return false; 2.选择重发: 41 /简化

38、帧 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

39、s; s.sequence= -1; ack_nakchannel-enterqueue( s ); /* 函数名:selectrepeat:transfer 参数表: 功 能:循环传输帧、确认或者重传要求,直 到发送方所有帧都得到确认为止 */ void selectrepeat:transfer( ) for ( ; !sender-finished( ); ) selectrepeat:senderdo( ); selectrepeat:recieverdo( ); /* 函数名:selectrepeat:senderdo 参数表: 功 能:如果信道不满,发送方发送一个帧; 如果有确认或

40、重传要求,发送方接收一个确认 或重传要求 */ 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 ); 42 /* 函数名:selectrepeat:recieverdo 参数表: 功 能:如果信道不空,接收方接收一个帧; 如果确认或重传要求的信道不满,接收方发送

41、 一个确认或重传要求 */ 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:

42、 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, recieverwindowsize ); delete wrong; select_repeat-transfer( ); /传输完毕,关闭程序 cout n 传输完毕。 endl; delete select_repeat; cout inputcontinue; system( cls ); if ( inputcontinue = y | inp

温馨提示

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

最新文档

评论

0/150

提交评论