ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:130.18KB ,
资源ID:3319873      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3319873.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(TCP IP课程设计.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

TCP IP课程设计.docx

1、TCP IP课程设计枣 庄 学 院信息科学与工程学院课程设计任务书 题目: PING 程序的设计与实现 学 号: 姓 名: 专 业: 计算机科学与技术 课 程: TCP/IP 协议实现与网络安全 指导教师: 王 霞 职称: 讲 师 完成时间: 2012年 6月-2012年 6 月枣庄学院信息科学与工程学院制 年 月 日课程设计任务书及成绩评定课程设计的任务和具体要求(1)熟悉原始套接字编程。(2)了解网络的结构。(3)了解网络传输底层协议。指导教师签字: 日期: 指导教师评语成绩: 指导教师签字: 日期: 课程设计所需软件、硬件等课程设计进度计划起至日期工作内容备注参考文献、资料索引序号文献、

2、资料名称编著者出版单位【1】 Winsock Programmers FAQ Examples: Ping: Raw Sockets Method,【2】 透析ICMP协议:协议原理,【3】 ping 原理与ICMP协议,目录一需求分析 1二概要设计 1三详细设计 31. 初始化模块 32. 功能控制模块 33. 数据报解读模块 64. Ping 测试模块 8四测试结果 11五实验总结 12一需求分析 Ping的原理就是首先建立通道,然后发送包,对方接受后返回信息,这个包至少包括以下内容:发送的时候,包的内容包括对方的ip地址和自己的地址,还有序列数;回送的时候包括双方地址,还有时间等,主要是

3、接受方在都是在操作系统内核里做好的,时刻在监听。Ping程序生成一个icmp“回送请求”,将其发送给目的主机。通过检测是否可以收到目标主机的应答,便可以知道网络的连通性。主要功能有:实现ping功能。程序能实现基本的ping操作,发送ICMP回显请求报文,接收显应答报文。能记录路由。程序提供了“-r”选项,用以记录从源主机到目的主机的路由。(3)能输出指定条数的记录。程序提供了“-n”选项,用以输出指定条数的记录。(4)能按照指定大小输出每条记录。程序提供了“datasize”选项,用以指定输出的数据报的大小。(5)能输出用户帮助。程序提供了用户帮助,显示程序提供的选项以及选项格式等。二概要设

4、计1) IntPing()函数原型:void IntPing()IntPing()函数用于初始化ping 所需的全局变量,为各个变量赋初始值。2)userHelp()函数原型:void userHelp() userHelp()函数用于显示用户帮助信息。当程序检查到参数错误或者没有必要的参数(如主机IP地址或者主机名)时,则会调用此函数显示帮助信息。3) GetArgments()函数原型:void GetArgments(int argc, char*argv)GetArgments()函数用于获取用户提交的参数。其中argc 表示获取的参数个数,argv 用于存储获取的参数,这两个形参和主

5、函数中的形参表示的意义一样的。4)checkSum()函数原型:USHORT checkSum(USHORT *buffer,int size)checkSum()函数用于计算校验和。计算过程是首先把数据报头中的校验和字段设置为0,然后对首部中每个16bit 进行二字段进制反码求和(整个首部看成是由一串16bit的字组成),结果存在校验和字段中。 其中buffer 用于存放ICMP数据,size表示ICMP报文大小。5)FillCMPData()函数原型:void FillCMPData()FillCMPData()函数用于填充ICMP数据报中各个字段。其中icmp_data 表示ICMP数据

6、,datasize 表示ICMP报文大小。6) reeRes()函数原型:void reeRes()reeRes()函数用于释放占用的资源,包括关闭初始化socket 调用的函数的、关闭创建的socket和释放分配的内存等。7)DecodeIPOptions()函数原型:void DecodeIPOptions()DecodeIPOptions()函数用于解读IP选项,从中读出从源主机到目的主机经过的路由,并输出路由信息。Buf表示存放接收到的ICMP报文的缓冲区,bytes表示接收到的字节数。8)DecodelICMPHeader()函数原型:void DecodelICMPHeader(c

7、har*buf,int bytes,SOCKADDR_IN*from)DecodelICMPHeader()函数用于解读ICMP报文信息。Buf表示存放接收到的ICMP报文的缓冲区,bytes表示接收到的字节数,from 表示发送ICMP回显应答的主机IP地址。9)PingTest() 函数原型:void PingTest(int timeout)PingTest()函数用于进行Ping操作。其中timeout表示设定的发送超时值。三详细设计1. 初始化模块/*初始化变量函数*/void InitPing() WSADATA wsaData; icmp_data = NULL; seq_no

8、= 0; recvbuf = NULL; RecordFlag = FALSE; lpdest = NULL; datasize = DEF_PACKET_SIZE; PacketNum = 5; SucessFlag = FALSE; /*Winsock初始化*/ if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) /*如果初始化不成功则报错,GetLastError()返回发生的错误信息*/ printf(WSAStartup() failed: %dn, GetLastError(); return ; m_socket = INVALID_SO

9、CKET;2. 功能控制模块/*显示信息函数*/void UserHelp() printf(UserHelp: ping -r data sizen); printf( -r record routen); printf( -n record amountn); printf( host remote machine to pingn); printf( datasize can be up to 1KBn); ExitProcess(-1); /*获取ping选项函数*/void GetArgments(int argc,char* argv) int i; int j; int exp;

10、 int len; int m; /*如果没有指定目的地地址和任何选项*/ if(argc = 1) printf(nPlease specify the destination IP address and the ping option as follow!n); UserHelp(); for(i = 1; i =1;j-,exp+) /*根据argvij中的ASCII值计算要获取的记录条数(十进制数)*/ PacketNum += (double)(argvij-48)*pow(10,exp); else switch (tolower(argvi1) /*选项指示要获取路由信息*/

11、case r: RecordFlag = TRUE; break; /*没有按要求提供选项*/ default: UserHelp(); break; /*参数是数据报大小或者IP地址*/ else if (isdigit(argvi0) for(m=1;m 1) cksum += *buffer+; size -= sizeof(USHORT); if (size) cksum += *(UCHAR*)buffer; /*对每个16bit进行二进制反码求和*/ cksum = (cksum 16) + (cksum & 0xffff); cksum += (cksum 16); return

12、 (USHORT)(cksum);/*填充ICMP数据报字段函数*/void FillICMPData(char *icmp_data, int datasize) IcmpHeader *icmp_hdr = NULL; char *datapart = NULL; icmp_hdr = (IcmpHeader*)icmp_data; /*ICMP报文类型设置为回显请求*/ icmp_hdr-i_type = ICMP_ECHO; icmp_hdr-i_code = 0; /*获取当前进程IP作为标识符*/ icmp_hdr-i_id = (USHORT)GetCurrentProcessI

13、d(); icmp_hdr-i_cksum = 0; icmp_hdr-i_seq = 0; datapart = icmp_data + sizeof(IcmpHeader); /*以数字0填充剩余空间*/ memset(datapart,0,datasize-sizeof(IcmpHeader);/*释放资源函数*/void FreeRes() /*关闭创建的套接字*/ if (m_socket != INVALID_SOCKET) closesocket(m_socket); /*释放分配的内存*/ HeapFree(GetProcessHeap(), 0, recvbuf); Heap

14、Free(GetProcessHeap(), 0, icmp_data); /*注销WSAStartup()调用*/ WSACleanup(); return ;3. 数据报解读模块/*解读IP选项头函数*/void DecodeIPOptions(char *buf, int bytes) IpOptionHeader *ipopt = NULL; IN_ADDR inaddr; int i; HOSTENT *host = NULL; /*获取路由信息的地址入口*/ ipopt = (IpOptionHeader *)(buf + 20); printf(RR: ); for(i = 0;

15、 i ptr / 4) - 1; i+) inaddr.S_un.S_addr = ipopt-addri; if (i != 0) printf( ); /*根据IP地址获取主机名*/ host = gethostbyaddr(char *)&inaddr.S_un.S_addr,sizeof(inaddr.S_un.S_addr), AF_INET); /*如果获取到了主机名,则输出主机名*/ if (host) printf(%-15s) %sn, inet_ntoa(inaddr), host-h_name); /*否则输出IP地址*/ else printf(%-15s)n, ine

16、t_ntoa(inaddr); return;/*解读ICMP报头函数*/void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN *from) IpHeader *iphdr = NULL; IcmpHeader *icmphdr = NULL; unsigned short iphdrlen; DWORD tick; static int icmpcount = 0; iphdr = (IpHeader *)buf; /*计算IP报头的长度*/ iphdrlen = iphdr-h_len * 4; tick = GetTickCoun

17、t(); /*如果IP报头的长度为最大长度(基本长度是20字节),则认为有IP选项,需要解读IP选项*/ if (iphdrlen = MAX_IP_HDR_SIZE) & (!icmpcount) /*解读IP选项,即路由信息*/ DecodeIPOptions(buf, bytes); /*如果读取的数据太小*/ if (bytes sin_addr); icmphdr = (IcmpHeader*)(buf + iphdrlen); /*如果收到的不是回显应答报文则报错*/ if (icmphdr-i_type != ICMP_ECHOREPLY) printf(nonecho type

18、 %d recvdn, icmphdr-i_type); return; /*核实收到的ID号和发送的是否一致*/ if (icmphdr-i_id != (USHORT)GetCurrentProcessId() printf(someone elses packet!n); return ; SucessFlag = TRUE; /*输出记录信息*/ printf(%d bytes from %s:, bytes, inet_ntoa(from-sin_addr); printf( icmp_seq = %d. , icmphdr-i_seq); printf( time: %d ms,

19、tick - icmphdr-timestamp); printf(n); icmpcount+; return;4. Ping 测试模块/*ping函数*/void PingTest(int timeout) int ret; int readNum; int fromlen; struct hostent *hp = NULL; /*创建原始套接字,该套接字用于ICMP协议*/ m_socket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,WSA_FLAG_OVERLAPPED); /*如果套接字创建不成功*/ if (m_so

20、cket = INVALID_SOCKET) printf(WSASocket() failed: %dn, WSAGetLastError(); return ; /*若要求记录路由选项*/ if (RecordFlag) /*IP选项每个字段用0初始化*/ ZeroMemory(&IpOption, sizeof(IpOption); /*为每个ICMP包设置路由选项*/ IpOption.code = IP_RECORD_ROUTE; IpOption.ptr = 4; IpOption.len = 39; ret = setsockopt(m_socket, IPPROTO_IP, I

21、P_OPTIONS,(char *)&IpOption, sizeof(IpOption); if (ret = SOCKET_ERROR) printf(setsockopt(IP_OPTIONS) failed: %dn,WSAGetLastError(); /*设置接收的超时值*/ readNum = setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(timeout); if(readNum = SOCKET_ERROR) printf(setsockopt(SO_RCVTIMEO) failed:

22、%dn,WSAGetLastError(); return ; /*设置发送的超时值*/ timeout = 1000; readNum = setsockopt(m_socket, SOL_SOCKET, SO_SNDTIMEO,(char*)&timeout, sizeof(timeout); if (readNum = SOCKET_ERROR) printf(setsockopt(SO_SNDTIMEO) failed: %dn,WSAGetLastError(); return ;/*用0初始化目的地地址*/ memset(&DestAddr, 0, sizeof(DestAddr)

23、; /*设置地址族,这里表示使用IP地址族*/ DestAddr.sin_family = AF_INET; if (DestAddr.sin_addr.s_addr = inet_addr(lpdest) = INADDR_NONE) /*名字解析,根据主机名获取IP地址*/ if (hp = gethostbyname(lpdest) != NULL) /*将获取到的IP值赋给目的地地址中的相应字段*/ memcpy(&(DestAddr.sin_addr), hp-h_addr, hp-h_length); /*将获取到的地址族值赋给目的地地址中的相应字段*/ DestAddr.sin_

24、family = hp-h_addrtype; printf(DestAddr.sin_addr = %sn, inet_ntoa(DestAddr.sin_addr); /*获取不成功*/ else printf(gethostbyname() failed: %dn,WSAGetLastError(); return ; /*数据报文大小需要包含ICMP报头*/ datasize += sizeof(IcmpHeader); /*根据默认堆句柄,从堆中分配MAX_PACKET内存块,新分配内存的内容将被初始化为0*/ icmp_data =(char*) HeapAlloc(GetProc

25、essHeap(), HEAP_ZERO_MEMORY,MAX_PACKET);recvbuf =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET);/*如果分配内存不成功*/ if (!icmp_data) printf(HeapAlloc() failed: %dn, GetLastError(); return ; /* 创建ICMP报文*/ memset(icmp_data,0,MAX_PACKET);FillICMPData(icmp_data,datasize); while(1) static int

26、nCount = 0; int writeNum; /*超过指定的记录条数则退出*/ if (nCount+ = PacketNum) break;/*计算校验和前要把校验和字段设置为0*/ (IcmpHeader*)icmp_data)-i_cksum = 0; /*获取操作系统启动到现在所经过的毫秒数,设置时间戳*/ (IcmpHeader*)icmp_data)-timestamp = GetTickCount(); /*设置序列号*/ (IcmpHeader*)icmp_data)-i_seq = seq_no+; /*计算校验和*/ (IcmpHeader*)icmp_data)-i

27、_cksum = CheckSum(USHORT*)icmp_data, datasize);/*开始发送ICMP请求 */ writeNum = sendto(m_socket, icmp_data, datasize, 0,(struct sockaddr*)&DestAddr, sizeof(DestAddr); /*如果发送不成功*/ if (writeNum = SOCKET_ERROR) /*如果是由于超时不成功*/ if (WSAGetLastError() = WSAETIMEDOUT) printf(timed outn); continue; /*其他发送不成功原因*/ printf(sendto() failed: %dn, WSAGetLastError(); return ; /*

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1