计算机网络程序设计(c语言课程设计)

合集下载

C语言程序设计课程标准

C语言程序设计课程标准

C语言程序设计课程标准课程名称:C语言程序设计适用专业:计算机应用技术、软件技术、计算机网络技术、电子应用技术、自动化技术等1 课程定位和设计思路1-1 课程定位本课程是高职高专计算机应用技术、软件技术、计算机网络技术、电子应用技术、自动化技术等一门专业基础、必修课程。

本课程的目的是培养高职高专学生计算机编程基本思想、编程基本技能及逻辑思维能力,掌握运用C语言编程来解决岗位工作中实际问题的方法和步骤,为提高职业能力和拓展职业空间打下坚实基础。

学生毕业后工作岗位主要有程序员、计算机管理员、单片机应用设计员、网络应用等,在计算机控制、单片机应用、数控技术、电子技术等相关行业中都将使用C语言作为应用系统开发设计语言,C语言也是计算机大类专业中《数据结构》、《C#程序设计》、《Java程序设计》及其它编程语言类课程的前导课程,也是信息产业部计算机专业和软件专业水平资格考试(程序员级别)考试中要求的主要程序设计语言。

1-2 设计思路本课程依据计算机应用技术、软件技术、计算机网络技术、电子应用技术、自动化技术、计算机网络技术等专业的工作任务及职业能力分析表中的程序设计工作项目的要求设置的。

设计思路是:打破传统学科课程模式,转变为以任务或项目为中心,组织课程教学内容,通过讲练结合,使学生在完成工作任务或具体项目的过程中学会知识的应用,构建相关理论知识,发展职业能力。

课程内容突出对高职学生职业能力的训练,理论知识的选取紧紧围绕工作任务完成的需要来进行,同时又充分考虑了高等职业教育对理论知识学习的需要,并融合了相关职业资格证书对知识、技能和态度的要求。

项目设计以学生编程能力的培养为线索来进行。

教学过程中,要通过校企合作、校内实训基地建设等多种途径,采取工学结合、课程设计等形式,充分开发学习资源,给学生提供丰富的实践机会。

教学效果评价采取过程性评价与结果性评价相结合,理论与实践相结合,理论考试重点考核与实践能力紧密相关的知识,重点评价学生的职业能力。

《C语言程序设计》课程设计任务书-建电11412

《C语言程序设计》课程设计任务书-建电11412

《C语言》课程设计任务书一、性质与目的:本课程设计是学生学习完《C语言程序设计》课程后进行的一次全面的综合练习。

本课程设计的目的和任务:(1)巩固和加深学生对C语言课程的基本知识的理解和掌握;(2)掌握C语言编程和程序调试的基本技能;(3)利用C语言进行简单软件设计的基本思路和方法;(4)提高运用C语言解决实际问题的能力。

通过实习,加深学生对课堂所学基础知识的掌握与理解,提高学生对所学内容的综合运用能力;同时通过查询资料,培养学生自学、接受新知识能力,提高学习兴趣;增强学生程序设计能力,掌握编程技巧,培养学生实际上机调试能力。

二、基本要求:1、选题规定2、设计结束后,要求每个学生上交一份打印的实习报告。

3、设计期间,学生要服从指导教师统一安排,遵守机房制度。

4、严格遵守纪律,不迟到,不早退。

对于无故缺勤者,成绩按不及格处理。

三、设计内容:题目见后边附录四、课程设计的成绩评定a)实习期间的平时表现;b)设计任务的考核成绩;c)设计报告的批阅成绩。

根据以上的成绩由指导教师进行综合评定,成绩分优、良、中、及格和不及格五个等级。

五、实习进程实习为期一周,共22学时,周一至周四每天利用半天时间查阅资料,另外半天到计算机房调试程序(上机的具体时间遵照机房的安排),周五对所设计的软件进行上机考核验收,考核合格者书写设计报告(电子版和打印版),下周一交给指导教师。

六、设计报告格式首先是封面(如下图)其次是目录(要求根据报告内容自动生成)一、设计思路二、程序流程图三、源程序清单四、程序运行结果五、设计总结六、教师评语(学生不要填写)然后是根据目录而写的具体内容附录:(一)基础部分:1.输入一个五位整数,将它反向输出。

例如输入12345,输出应为54321。

(15分)2.用两种循环结构分别编程计算1+2+3…+100的值。

运行结果为“1+2+…+100=5050”(15分)3. 从终端读入20个数据到数组中,统计其中正数的个数,并计算它们之和。

c语言课程设计是什么

c语言课程设计是什么

c语言课程设计是什么一、教学目标本课程旨在通过C语言的学习,让学生掌握C语言的基本语法、数据类型、运算符、控制结构、函数等基本知识,培养学生编程思维和解决问题的能力。

同时,通过编程实践,使学生能够运用C语言编写简单的程序,提高学生的动手能力和创新能力。

在教学过程中,注重培养学生的自主学习能力、团队协作能力和沟通表达能力,使学生在学习C语言的同时,也能够提升自身的综合素质。

二、教学内容教学内容主要包括C语言的基本语法、数据类型、运算符、控制结构、函数等基本知识。

具体包括:1.C语言的基本语法和编程规范;2.数据类型、变量和常量的使用;3.运算符和表达式的应用;4.控制结构(条件语句、循环语句等)的编程;5.函数的定义和调用;6.数组、指针和字符串的基本操作;7.结构体、共用体和枚举类型的使用;8.文件操作和错误处理。

三、教学方法为了提高教学效果,将采用多种教学方法相结合的方式进行教学。

主要包括:1.讲授法:通过讲解C语言的基本概念和编程方法,使学生掌握C语言的基本知识;2.案例分析法:通过分析典型程序案例,使学生理解编程思路和方法;3.实验法:安排上机实验,让学生动手编写程序,巩固所学知识;4.小组讨论法:学生进行小组讨论,培养学生的团队协作能力和沟通能力。

四、教学资源为了支持教学内容和教学方法的实施,将准备以下教学资源:1.教材:《C程序设计语言》(K&R);2.参考书:《C Primer Plus》、《C和指针》;3.多媒体资料:教学PPT、视频教程等;4.实验设备:计算机、网络环境等;5.在线资源:编程、论坛、开源项目等。

通过以上教学资源的支持,为学生提供丰富的学习体验,提高学生的学习效果。

五、教学评估本课程的教学评估将采用多元化评价方式,全面客观地评价学生的学习成果。

评估内容包括平时表现、作业、考试等。

具体评估方式如下:1.平时表现:通过课堂参与、提问、小组讨论等环节,评估学生的学习态度和参与程度;2.作业:布置适量的编程作业,评估学生的编程能力和实践能力;3.考试:包括期中和期末考试,主要评估学生对C语言知识的掌握程度和编程能力;4.项目:小组项目,让学生结合所学知识解决实际问题,评估学生的综合应用能力。

大一c语言程序课程设计

大一c语言程序课程设计

大一c语言程序课程设计一、课程目标知识目标:1. 理解C语言程序设计的基本概念,掌握数据类型、变量、运算符、表达式等基础知识;2. 学会使用顺序结构、分支结构、循环结构进行程序设计;3. 掌握数组和函数的使用,理解指针的概念及其应用;4. 了解结构体、联合体和枚举类型的使用。

技能目标:1. 能够运用C语言编写简单的程序,解决问题;2. 能够分析问题,运用逻辑思维进行程序设计;3. 能够阅读和理解他人编写的C语言程序;4. 能够对程序进行调试和优化,提高程序效率。

情感态度价值观目标:1. 培养学生的编程兴趣,激发学习积极性;2. 培养学生的团队合作意识,学会与他人共同解决问题;3. 培养学生的创新精神,敢于尝试新思路和方法;4. 培养学生严谨的学术态度,遵循编程规范。

课程性质:本课程为大一C语言程序设计的基础课程,旨在使学生掌握C语言的基本知识和编程技能,为后续专业课程打下坚实基础。

学生特点:大一学生刚接触编程,对编程知识有一定好奇心,但缺乏实际操作经验。

教学要求:结合学生特点,注重理论与实践相结合,通过案例分析和实际操作,使学生熟练掌握C语言编程技巧。

在教学过程中,注重培养学生的编程兴趣和创新能力,提高学生分析问题和解决问题的能力。

将课程目标分解为具体的学习成果,以便进行后续的教学设计和评估。

二、教学内容1. C语言概述:介绍C语言的发展历程、特点和应用领域,理解编程的基本概念。

相关教材章节:第一章2. 数据类型与运算符:讲解基本数据类型、变量定义、常量声明,运算符及其优先级。

相关教材章节:第二章3. 顺序结构程序设计:学习基本输入输出函数,编写简单的顺序结构程序。

相关教材章节:第三章4. 分支结构程序设计:介绍if语句、switch语句,学会编写分支结构程序。

相关教材章节:第四章5. 循环结构程序设计:讲解for循环、while循环、do-while循环,掌握循环结构编程。

相关教材章节:第五章6. 数组:介绍一维数组、二维数组的使用,学会存储和操作批量数据。

c语言课程设计学生选修课程

c语言课程设计学生选修课程

c语言课程设计学生选修课程一、教学目标本课程旨在让学生掌握C语言的基本语法、数据结构、算法和编程技巧,培养学生独立思考和解决问题的能力。

通过本课程的学习,学生将能够熟练使用C语言进行程序设计,具备一定的软件开发能力。

具体的教学目标如下:1.知识目标:(1)了解C语言的发展历程和特点;(2)掌握C语言的基本语法和编程规范;(3)熟悉常用的数据类型、运算符和表达式;(4)理解函数的定义和调用方法;(5)掌握数组、指针和字符串的使用;(6)了解常用的高级数据结构及其应用;(7)掌握基本的算法和编程技巧。

2.技能目标:(1)能够使用C语言编写简单的程序;(2)具备阅读和理解C语言程序的能力;(3)掌握常用的调试工具和技巧;(4)能够独立思考和解决问题;(5)具备一定的软件开发能力。

3.情感态度价值观目标:(1)培养学生对计算机科学的兴趣和热情;(2)培养学生良好的编程习惯和团队协作精神;(3)培养学生具有较强的自学能力和创新意识;(4)培养学生具备良好的道德品质和职业素养。

二、教学内容本课程的教学内容主要包括C语言的基本语法、数据结构、算法和编程技巧。

具体安排如下:1.C语言的基本语法:(1)C语言的发展历程和特点;(2)基本数据类型、运算符和表达式;(3)程序的流程控制语句;(4)函数的定义和调用;(5)数组、指针和字符串的使用。

2.数据结构:(1)顺序结构;(2)选择结构;(3)循环结构;(4)常用的高级数据结构及其应用。

3.算法和编程技巧:(1)常用的排序算法;(2)查找算法;(3)常用的数据处理方法;(4)面向对象编程思想。

三、教学方法本课程采用多种教学方法,包括讲授法、讨论法、案例分析法和实验法等。

具体应用如下:1.讲授法:用于讲解C语言的基本语法、数据结构和算法;2.讨论法:用于探讨编程技巧和解决问题的方式;3.案例分析法:通过分析典型的程序案例,使学生更好地理解编程思想;4.实验法:让学生动手编写程序,培养实际操作能力。

《C语言程序设计课设》课程设计指导书

《C语言程序设计课设》课程设计指导书

《C语言程序设计课设》课程设计指导书一、课程设计的目的(1)加深对讲授内容的理解,尤其是一些语法规则。

(2)熟悉C语言程序设计的结构化编程的思想,掌握数据的基本类型、自定义类型、函数、文件和指针等知识,能运用这些知识进行综合编程,熟练应用。

(3)能够综合运用所学知识,编程解决实际问题。

(4)培养团队分工合作的意识,最终使学生提高编程技能和解决实际问题的能力。

二、课程设计基本要求2.1.组织管理1.由院、系指派经验丰富的专业教师担任指导教师。

2.课程设计实行课程负责人与指导教师共同负责制。

3.课程负责人主要进行课设的命题、指导教师的考核、技术把关和全面管理。

4.指导教师全面负责所承担班级的课程设计指导、管理和考核评定工作。

2.2设计要求1.自选题目、小组管理、团队合作、小组评测。

2.模块化程序设计。

3.锯齿型书写格式。

4.必须上机调试通过。

三、选题要求:每个题目限定1-2人,每人必须负责一部分功能,并独立完成,推举出一个组长,负责任务分工,汇总到班长处,然后交给指导教师。

四、设计报告格式及要求:1、题目2、设计目的3、总体设计(程序设计组成框图、流程图)4、详细设计(模块功能说明(如函数功能、入口及出口参数说明,函数调用关系描述等)5、运行结果及分析6、调试与测试:调试方法,测试结果的分析与讨论,测试过程中遇到的主要问题及采取的解决措施7、课程设计心得及体会8、源程序清单和执行结果:清单中应有足够的注释五、课程设计成绩评定5.1基本要求:(1)每个人必须有程序运行结果;(2)每个人必须交《C语言课程设计》报告5.2、成绩评定和打分标准由指导教师对学生在课程设计期间的表现,所完成的设计报告的质量、设计结果的验收和答辩情况进行综合考核。

具体评定标准如下:(1)上机考勤:注重平时上机考勤与遵守纪律情况20%(2)结果验收:学生能运行、讲述或调试自己的程序,回答教师提问,每个人必须有程序运行结果40%(3)小组自评成绩结果10%(4)设计报告:每个人必须交《C语言课程设计》报告和《C语言课程设计》日志30%以上四项缺一不可,否则不能到得相应学分依据上述考核内容,最后采用优(>90分)、良(80~89分)、中(70~79分)及格(60~69分)、不及格(<60分)五级记分制评定学生课程设计成绩。

《C语言程序设计》课程教学大纲

《C语言程序设计》课程教学大纲

对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,通系电1,力过根保管据护线生高0不产中仅工资2艺料22高试2可中卷以资配解料置决试技吊卷术顶要是层求指配,机置对组不电在规气进范设行高备继中进电资行保料空护试载高卷与中问带资题负料2荷试2,下卷而高总且中体可资配保料置障试时2卷,32调需3各控要类试在管验最路;大习对限题设度到备内位进来。行确在调保管整机路使组敷其高设在中过正资程常料1工试中况卷,下安要与全加过,强度并看工且25作尽52下可22都能护可地1关以缩于正小管常故路工障高作高中;中资对资料于料试继试卷电卷连保破接护坏管进范口行围处整,理核或高对者中定对资值某料,些试审异卷核常弯与高扁校中度对资固图料定纸试盒,卷位编工置写况.复进保杂行护设自层备动防与处腐装理跨置,接高尤地中其线资要弯料避曲试免半卷错径调误标试高方中等案资,,料要编试求5写、卷技重电保术要气护交设设装底备备置。4高调、动管中试电作线资高气,敷料中课并设3试资件且、技卷料中拒管术试试调绝路中验卷试动敷包方技作设含案术,技线以来术槽及避、系免管统不架启必等动要多方高项案中方;资式对料,整试为套卷解启突决动然高过停中程机语中。文高因电中此气资,课料电件试力中卷高管电中壁气资薄设料、备试接进卷口行保不调护严试装等工置问作调题并试,且技合进术理行,利过要用关求管运电线行力敷高保设中护技资装术料置。试做线卷到缆技准敷术确设指灵原导活则。。:对对在于于分调差线试动盒过保处程护,中装当高置不中高同资中电料资压试料回卷试路技卷交术调叉问试时题技,,术应作是采为指用调发金试电属人机隔员一板,变进需压行要器隔在组开事在处前发理掌生;握内同图部一纸故线资障槽料时内、,设需强备要电制进回造行路厂外须家部同出电时具源切高高断中中习资资题料料电试试源卷卷,试切线验除缆报从敷告而设与采完相用毕关高,技中要术资进资料行料试检,卷查并主和且要检了保测解护处现装理场置。设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。

《C语言程序设计》课程标准

《C语言程序设计》课程标准

《C语言程序设计》课程标准课程名称:C语言程序设计课程编码:60415001总学时数:84适用专业:网络技术,软件技术,多媒体技术,电子技术等一、课程概述1.课程定位《C语言程序设计》课程是高职高专计算机类和电子信息类各专业职业素质必修课,旨在培养高职学生运用计算机进行逻辑思维的能力,掌握运用C语言编程来解决岗位工作中实际问题的方法和步骤,为提高职业能力和拓展职业空间打下坚实基础。

所以,本课程主要针对培养这类人才基本程序设计能力的目的而设置的课程。

学生毕业后工作岗位主要有程序员、计算机管理员、数据库管理员、软件测试等,在计算机各专业等相关行业中都将使用C语言作为应用系统开发设计语言,C语言也是计算机应用专业中《Java程序设计》、《C#程序设计》及其它编程语言类课程的前导课程,也是信息产业部计算机专业和软件专业水平资格考试要求的主要程序设计语言。

2.课程设计思路本课程以“学生成绩管理系统”项目作为主线,采用边讲边练的教学互动形式,同时应用案例教学法,在课堂上导入贴近实际的程序设计实例。

教学过程中,首先提出项目目标,然后通过知识讲解、方法演示、实践演练、复习归纳,以解决实际问题的学习方法来学习软件开发。

二、课程目标1.总体目标通过本课程的学习,使学生能够具有结构化程序设计的思想,能够用C语言进行简单程序的编写,能够熟练的进行程序的调试和修改,同时具备软件开发所需要的协作精神,较强的上进心和责任感。

2.具体目标(1)职业技能目标○1培养学生编写规范化的程序代码○2自主的学习能力○3掌握面向过程编程的思想○4能够编制简单的C语言应用程序(2)知识目标○1掌握C语言的数据类型的定义与使用○2掌握程序结构设计的方法○3掌握数组定义与使用的方法○4掌握函数定义与使用的方法○5掌握指针的使用方法○6掌握文件的概念与使用方法(3)职业素质养成目标○1服务意识:能够为他人提供优质的服务○2文明、法制意识;合理利用所学知识,不做危害他人和社会的事○3吃苦精神:能承受软件开发带来的体力和脑力的压力○4合作精神:能够与他人进行合作,具有协调工作能力和组织管理能力○5较强的自我知识及技术更新能力;快速跟踪社会前沿技术及市场应用动态三、课程内容与要求表1 课程总体设计表2 学习单元设计四、实施建议(一)考核评价建议本课程采用理论考加题签的考试形式,即课程的总成绩由平时成绩(20%)+实验成绩(30%)+考试成绩(50%),课程实训单独计算成绩。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ping程序设计ping命令是使用频率极高的一个网络测试命令,用以测试从一个主机到另一个主机间的网络上否可达。

windows自带的ping命令具有强大的功能,它有很多选项用于实现不同的测试目的。

本章模仿windows的ping命令,用c语言实现了一个简单的命令。

本章着重讲述ping命令的实现原理和c语言的网络编程方法。

读者可以在本章的基础上,对本章实现的ping命令进行扩展,开发出功能更强大、更完善的ping命令,并进一步掌握网络编程的方法。

9.1 设计目的本章通过设计Ping程序,讲解Ping程序的实现原理,并初步讲解了c语言网络编程技术。

本章涉及很多网络编程函数和编程技巧。

包括库文件的导入;winsock的初始化、注销;socket 的创建、关闭;设置socket选项;根据主机名获取IP地址;从堆中分配一定数量的空间、释放从堆中分配的空间;获取当前进程ID号;数据报的发送;数据报的接等。

通过本程序的训练,使读者对网络编程有一定的了解,掌握Ping程序的设计方法,掌握网络编程的方法和技巧,从而编写出功能更强大的程序。

9.2功能描述本章用 c 语言实现的ping命令,能用于测试一个主机到另一个主机间的联通情况,程序还提供了几个选项以实现不同的功能。

(1)实现ping功能。

程序能实现基本的ping操作,发送ICMP回显请求报文,接收显应答报文。

(2)能记录路由。

程序提供了“-r”选项,用以记录从源主机到目的主机的路由。

(3)能输出指定条数的记录。

程序提供了“-n”选项,用以输出指定条数的记录。

(4)能按照指定大小输出每条记录。

程序提供了“datasize”选项,用以指定输出的数据报的大小。

(5)能输出用户帮助。

程序提供了用户帮助,显示程序提供的选项以及选项格式等。

9.3 总体设计9.3.1 功能模块设计1. 功能模块图本系统共有 4 个模块,分别是初始化模块、功能控制模块、数据控制模块、数据报解读模块和ping测试模块,如图9.1所示。

各模块功能描述如下。

图9.1 系统模块图(1) 初始化模块。

改模块用于初始化各个全局变量,为全局变量赋初始值;初始化,加载库。

(2)功能控制模块。

改模块是被其它模块调用,其功能包括获取参数、计算校验和填充数据报文、释放占用资源和显示用户帮助。

(3)数据报解读模块。

改模块用于解读接收到的报文和选项。

(4)测试模块。

改模块是本程序的核心模块,调用其他模块实现其功能,主要是实现的功能。

2.系统流程图系统执行的流程图9.2所示。

程序首先调用IniPing()函数初始化各全局变量,然后GetArgments()函数获取用户输入的参数,检查用户输入的参数,如果参数不正确或者没有输入参数,则显示用户帮助信息(User help ),并结束程序;如果参数正确,则对指定目的地执行Ping命令,如果Ping通,则显示Ping结果并释放占用资源,如果没有Ping通,则报告错误信息,并释放占用资源。

图9.2 系统流程图3.参数获取(GetArgments()函数)流程图获取的参数包括“-r”(记录路由)、“-n”(记录条数程序,任意的整数)和datasize(数据报大小)。

程序首先判断每一个参数的第一字符,如果第一个字符是“-”(短横线),则认为是“-r”或者“-n”中的一个,然后作进一步判断。

如果该参数的第二个字符是数字,则判断该参数为记录的条数,如果该参数的第二个字符是“r”,则判断该参数为“-r”,用于记录路由;如果参数的第一个字符是数字,则认为参数是IP地址;或者datasize,然后作进一步的判断。

如果该参数中不存在非数字的字符,则判断该参数为datasize;如果存在非数字的字符,则判断该参数为IP地址;其他情况则判断为主机名。

参数获取的流程如图9.3所示。

图9.3 参数获取流程图4.ping()函数流程图ping()函数是本程序的核心部分它调用其他模块的函数来实现,其主要步骤包括创建接字,设置路由选项(如果需要的话)、设置接收和发送超时值、名字解析(如果需要的话)、分配内存、创建ICMP报文、发送ICMP请求报文、接收ICMP应答报文和解读ICMP报文。

其执行流程如图9.4所示。

图9.4 Ping 函数流程图9.3.2数据结构设计本程序定义了3个结构体:-iphdr、-icmphdr、和-ipotionhdr,分别用于存放IP报头信息、ICM P报头信息和IP路由选项信息。

1.定义IP报头结构体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_flags;Unsigned char ttl;Unsigned chor proto;Unsigned short checksum;Unsigned int sourceIP;Unsigned int destIP;} IpHeader;h-len:4 : 表示IP报头长度,首部长度指的是首部占32bit字的数目,包括任何选项。

由于它是一个4bit 字段,因此首部最长为60个字节,不包括任何选项的IP报头是20个字节。

Version:4: 表示IP的版本号,这里表示Ipv4.。

Top: 表示服务的类型,可以表示最小时延,最大吞吐量,最高可靠性和最小费用。

Total –len: 整个IP数据报的总长度。

Ident: 唯一的标识符,标识主机发送的每一份数据报。

Frag-flags: 分段标志,表示过长的数据报是否要分段。

Ttl: 生存期,表示数据报可以经过的最多路由器数。

Proto: 协议类型(TCP、UDP等)。

Checksum: 校验和。

sourceIP: 源IP地址。

destIP: 目的IP地址。

2.定义ICMP报头结构体Typedef struct –icmphdr{BYTE i_type;BYTE i_code :USHORT i_cksum;USHORT i_id;USHORT i_seq;ULONG timestamp;} IcmpHeader;其中各字段表示意义如下。

I_tye : ICMP报文类型。

I_code : 该类型中的代码号,一种ICMP 报文的类型号和该类型中的代码号共同决定。

、I_cksum: 校验和。

I_seq: 序列号,序列号从0开始,每发送一次新的回显请求就加1. Timestamp: 时间。

3.定义IP 选项结构体Typedef struct _ipoptionhdr{Unsigned char code;Unsigned char len;Unsigned char ptr;Unsigned loang addr[9];} IcmpHeader;Code: 指明IP 选项类型,对于路由记录选项,它的值是7。

Len: 选项头长度。

Ptr: 地址指针字段,是一个基于1的指针,指向存放下一个IP地址的位置。

addr[9]: 记录的Ip地址列表,由于IP首部中选项的空间有限,所以可以记录的Ip地址最多是9个。

9.33函数功能描述1)IntPing()函数原型:void IntPing()IntPing()函数用于初始化ping 所需的全局变量,为各个变量赋初始值。

2)userHelp()函数原型:void userHelp()userHelp()函数用于显示用户帮助信息。

当程序检查到参数错误或者没有必要的参数(如主机IP地址或者主机名)时,则会调用此函数显示帮助信息。

3) GetArgments()函数原型:void GetArgments(int argc, char**argv)GetArgments()函数用于获取用户提交的参数。

其中argc 表示获取的参数个数,argv 用于存储获取的参数,这两个形参和主函数中的形参表示的意义一样的。

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数据,datasize 表示ICMP报文大小。

6) reeRes()函数原型:void reeRes()reeRes()函数用于释放占用的资源,包括关闭初始化socket 调用的函数的、关闭创建的socket和释放分配的内存等。

7)DecodeIPOptions()函数原型:void DecodeIPOptions()DecodeIPOptions()函数用于解读IP选项,从中读出从源主机到目的主机经过的路由,并输出路由信息。

Buf表示存放接收到的ICMP报文的缓冲区,bytes表示接收到的字节数。

8)DecodelICMPHeader()函数原型:void DecodelICMPHeader(char*buf,int bytes,SOCKADDR_IN*from) DecodelICMPHeader()函数用于解读ICMP报文信息。

Buf表示存放接收到的ICMP报文的缓冲区,bytes表示接收到的字节数,from 表示发送ICMP回显应答的主机IP地址。

9)PingTest()函数原型:void PingTest(int timeout)PingTest()函数用于进行Ping操作。

其中timeout表示设定的发送超时值。

9.4程序实现9.1.4 源码分析1. 程序预处理/*导入库文件*/#pragma comment( lib, "ws2_32.lib" )/*加载头文件*/#include <winsock2.h>#include <ws2tcpip.h>#include <stdio.h>#include <stdlib.h>#include <math.h>/*定义常量*//*表示要记录路由*/#define IP_RECORD_ROUTE 0x7/*默认数据报大小*/#define DEF_PACKET_SIZE 32/*最大的ICMP数据报大小*/#define MAX_PACKET 1024/*最大IP头长度*/#define MAX_IP_HDR_SIZE 60/*ICMP报文类型,回显请求*/#define ICMP_ECHO 8/*ICMP报文类型,回显应答*/#define ICMP_ECHOREPLY 0/*最小的ICMP数据报大小*/#define ICMP_MIN 8/*自定义函数原型*/void InitPing();void UserHelp();void GetArgments(int argc, char** argv);USHORT CheckSum(USHORT *buffer, int size);void FillICMPData(char *icmp_data, int datasize);void FreeRes();void DecodeIPOptions(char *buf, int bytes);void DecodeICMPHeader(char *buf, int bytes, SOCKADDR_IN* from); void PingTest(int timeout);/*IP报头字段数据结构*/typedef struct _iphdr{unsigned int h_len:4; /*IP报头长度*/unsigned int version:4; /*IP的版本号*/unsigned char tos; /*服务的类型*/unsigned short total_len; /*数据报总长度*/unsigned short ident; /*惟一的标识符*/unsigned short frag_flags; /*分段标志*/unsigned char ttl; /*生存期*/unsigned char proto; /*协议类型(TCP、UDP等)*/unsigned short checksum; /*校验和*/unsigned int sourceIP; /*源IP地址*/unsigned int destIP; /*目的IP地址*/} IpHeader;/*ICMP报头字段数据结构*/typedef struct _icmphdr{BYTE i_type; /*ICMP报文类型*/BYTE i_code; /*该类型中的代码号*/USHORT i_cksum; /*校验和*/USHORT i_id; /*惟一的标识符*/USHORT i_seq; /*序列号*/ULONG timestamp; /*时间戳*/} IcmpHeader;/*IP选项头字段数据结构*/typedef struct _ipoptionhdr{unsigned char code; /*选项类型*/unsigned char len; /*选项头长度*/unsigned char ptr; /*地址偏移长度*/unsigned long addr[9]; /*记录的IP地址列表*/ } IpOptionHeader;/*定义全局变量*/SOCKET m_socket;IpOptionHeader IpOption;SOCKADDR_IN DestAddr;SOCKADDR_IN SourceAddr;char *icmp_data;char *recvbuf;USHORT seq_no ;char *lpdest;int datasize;BOOL RecordFlag;double PacketNum;BOOL SucessFlag;2.初始化模块/*初始化变量函数*/void InitPing(){WSADATA wsaData;icmp_data = NULL;seq_no = 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: %d\n", GetLastError());return ;}m_socket = INV ALID_SOCKET;}3.功能控制模块/*显示信息函数*/void UserHelp(){printf("UserHelp: ping -r <host> [data size]\n");printf(" -r record route\n");printf(" -n record amount\n");printf(" host remote machine to ping\n");printf(" datasize can be up to 1KB\n");ExitProcess(-1);}/*获取ping选项函数*/void GetArgments(int argc,char** argv){int i;int j;int exp;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 < argc; i++){if (argv[i][0] == '-'){/*选项指示要获取记录的条数*/if(isdigit(argv[i][1])){PacketNum = 0;for(j=len-1,exp=0;j>=1;j--,exp++)/*根据argv[i][j]中的ASCII值计算要获取的记录条数(十进制数)*/PacketNum += ((double)(argv[i][j]-48))*pow(10,exp);}else{switch (tolower(argv[i][1])){/*选项指示要获取路由信息*/case 'r':RecordFlag = TRUE;break;/*没有按要求提供选项*/default:UserHelp();break;}}}/*参数是数据报大小或者IP地址*/else if (isdigit(argv[i][0])){for(m=1;m<len;m++){if(!(isdigit(argv[i][m]))){/*是IP地址*/lpdest = argv[i];break;}/*是数据报大小*/else if(m==len-1)datasize = atoi(argv[i]);}}/*参数是主机名*/else}}/*求校验和函数*/USHORT CheckSum(USHORT *buffer, int size){unsigned long cksum=0;while (size > 1){cksum += *buffer++;size -= sizeof(USHORT);}if (size){cksum += *(UCHAR*)buffer;}/*对每个16bit进行二进制反码求和*/cksum = (cksum >> 16) + (cksum & 0xffff);cksum += (cksum >>16);return (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)GetCurrentProcessId();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 != INV ALID_SOCKET)closesocket(m_socket);/*释放分配的内存*/HeapFree(GetProcessHeap(), 0, recvbuf);HeapFree(GetProcessHeap(), 0, icmp_data);/*注销WSAStartup()调用*/WSACleanup();return ;}4.数据报解读模块/*解读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; i < (ipopt->ptr / 4) - 1; i++){inaddr.S_un.S_addr = ipopt->addr[i];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) %s\n", inet_ntoa(inaddr), host->h_name);/*否则输出IP地址*/elseprintf("(%-15s)\n", inet_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 = GetTickCount();/*如果IP报头的长度为最大长度(基本长度是20字节),则认为有IP选项,需要解读IP选项*/if ((iphdrlen == MAX_IP_HDR_SIZE) && (!icmpcount))/*解读IP选项,即路由信息*/DecodeIPOptions(buf, bytes);/*如果读取的数据太小*/if (bytes < iphdrlen + ICMP_MIN){printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));}icmphdr = (IcmpHeader*)(buf + iphdrlen);/*如果收到的不是回显应答报文则报错*/if (icmphdr->i_type != ICMP_ECHOREPLY){printf("nonecho type %d recvd\n", icmphdr->i_type);return;}/*核实收到的ID号和发送的是否一致*/if (icmphdr->i_id != (USHORT)GetCurrentProcessId()){printf("someone else's 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", tick - icmphdr->timestamp);printf("\n");icmpcount++;return;}5.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_socket == INV ALID_SOCKET){printf("WSASocket() failed: %d\n", 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, IP_OPTIONS,(char *)&IpOption, sizeof(IpOption));if (ret == SOCKET_ERROR){printf("setsockopt(IP_OPTIONS) failed: %d\n",WSAGetLastError());}}/*设置接收的超时值*/readNum = setsockopt(m_socket, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(timeout));if(readNum == SOCKET_ERROR){printf("setsockopt(SO_RCVTIMEO) failed: %d\n",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: %d\n",WSAGetLastError());return ;}/*用0初始化目的地地址*/memset(&DestAddr, 0, sizeof(DestAddr));/*设置地址族,这里表示使用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_family = hp->h_addrtype;printf("DestAddr.sin_addr = %s\n", inet_ntoa(DestAddr.sin_addr));}/*获取不成功*/else{printf("gethostbyname() failed: %d\n",WSAGetLastError());return ;}}/*数据报文大小需要包含ICMP报头*/datasize += sizeof(IcmpHeader);/*根据默认堆句柄,从堆中分配MAX_PACKET内存块,新分配内存的内容将被初始化为0*/icmp_data =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET);recvbuf =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET);/*如果分配内存不成功*/if (!icmp_data){printf("HeapAlloc() failed: %d\n", GetLastError());return ;}/* 创建ICMP报文*/memset(icmp_data,0,MAX_PACKET);FillICMPData(icmp_data,datasize);while(1){static int 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_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 out\n");continue;}/*其他发送不成功原因*/printf("sendto() failed: %d\n", WSAGetLastError());return ;}/*开始接收ICMP应答*/fromlen = sizeof(SourceAddr);readNum = recvfrom(m_socket, recvbuf, MAX_PACKET, 0,(struct sockaddr*)&SourceAddr, &fromlen);/*如果接收不成功*/if (readNum == SOCKET_ERROR){/*如果是由于超时不成功*/if (WSAGetLastError() == WSAETIMEDOUT){printf("timed out\n");continue;}/*其他接收不成功原因*/printf("recvfrom() failed: %d\n", WSAGetLastError());return ;}/*解读接收到的ICMP数据报*/DecodeICMPHeader(recvbuf, readNum, &SourceAddr);}}6.主函数int main(int argc, char* argv[]){InitPing();GetArgments(argc, argv);PingTest(1000);/*延迟1秒*/Sleep(1000);if(SucessFlag)printf("\nPing end, you have got %.0f records!\n",PacketNum);elseprintf("Ping end, no record!");FreeRes();getchar();return 0;}。

相关文档
最新文档