基于Socket的PING程序设计
基于lwip socket的tcp客户端例程
charbuffer[BUFFER_SIZE];
structsockaddr_inserver_addr;
intlen;
// 获取当前时间并转换为字符串
time_tcurrent_time;
structtm*time_info;
chartime_str[20];
二、例程代码
#include<lwip/lwip.h>c
#include<lwip/sockets.h>
#include<lwip/sys.h>
#include<string.h>
#defineSERVER_IP"服务器ip"
#defineSERVER_PORT 12345
#defineBUFFEt;0) {
printf("socket() failed: %s\n",strerror(errno));
return-1;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port =htons(SERVER_PORT);
server_addr.sin_addr.s_addr =inet_addr(SERVER_IP);
time(¤t_time);
time_info =localtime(¤t_time);
strftime(time_str,sizeof(time_str),"%Y-%m-%d %H:%M:%S", time_info);
// 构建要发送的数据
计算机网络课程设计实验报告
计算机网络课程设计报告姓名:学号:班级:指导老师:湖南科技大学计算机科学与工程学院2013年6月实验一1。
实验名称:网络聊天程序的设计与实现2。
实验目的:通过本实验能够了解socket通信的原理并在此基础上编写一个聊天程序了解TCP/IP的基础知识,发现TCP与UDP的优缺点以及在网络通信的应用.3.实验原理:从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。
当网络的边缘部分中的两个主机使用网络的两个主机使用网络的核心部分进行端到端的通信时,只有主机的协议栈才有运输层,而网络核心部分中的路由器在转发分组时都只用到下三层的功能。
从IP层来说,通信的两端是两个主机,IP数据报的首部明确的标志了这两个主机的IP地址.但是严格的讲,两个主机进行通信就是两个主机中的应用进程互相通信。
根据应用程序的不同需求,运输层需要有两种不同的运输协议,即是面向连接的TCP和无连接的UDP。
在使用这两个协议时运输层向高层用户屏蔽了下面的网络核心的细节,它使应用进程看见的就是好像在两个运输层实体间有一条端到端的逻辑通信信道,但这条逻辑通信信道对上层的表现却因运输层使用的不同协议而有很大的差别.当运输层采用面向连接的TCP协议时,尽管下面的网络是不可靠的,但这种逻辑通信信道就相当于一条全双工的可靠信道。
但当运输层采用无连接的UDP协议时,这种逻辑通信信道仍然是一条不可靠信道.由于我在课程设计中采用的是UDP协议进行通信的,这里就只简述一下一些关于UDP的内容,UDP在传送数据之前不需要先建立连接。
远地主机的运输层在收到UDP报文后,不需要给出任何确认。
虽然UDP不提供可靠的交付,但在某些情况下UDP却是一种最有效的工作方式.为此当我们使用UTP协议使两个计算机中的进程要互相通信,不仅必需知道对方的IP地址(为了找到对方的计算机),而且还要知道对方的端口号(为了找到对方计算机中的应用进程)。
基于SOCKET的即时通信系统设计与实现教材
摘要随着网络通信技术和计算机技术的进一步发展,即时通信(Instant Messaging)正在成为网络在线活动中不可缺少的业务,对它的研究是互联网应用中一个热点课题。
即时通信软件的诞生,推动了企业工作效率的提高,降低了办公费用,给企业的管理带来了新的思路和方法,并引起了人们对该应用领域的关注。
本文在现有的网络通信技术、数据库技术和信息安全技术的基础上设计并实现了新型的企业即时通信系统(EIM,Enterprise Instant Messaging)。
该系统为用户提供了一个集文字通信、文件传输于一体的即时通信平台,基本满足了企业用户的要求。
在对即时通信系统的服务器端和客户端的主要组成模块详细剖析后,论文研究了各个模块的详细设计和实现方式,分别研究了每个模块的主要功能,并给出了模块运行效果图。
系统实现后,对系统进行了功能测试,并分析测试数据。
实验数据表明,该系统具有易于实现、可靠性高、易于扩展、传输效率高等特点,达到了预定的设计目标。
关键词:即时通信,Socket,通信模型,文件传输AbstractWith the network communication technology and the further development of computer technology, instant messaging (Instant Messaging) is becoming an indispensable network of online business activities; its research is a hot topic in Internet applications. The birth of instant messaging software, to promote the work efficiency of the enterprise, reducing business costs, to the enterprise's management has brought new ideas and methods, and aroused the concern of the applications.The subject in the existing network communication technology, database technology and information security technology based on the design and implementation of a new type of enterprise instant messaging system (EIM, Enterprise Instant Messaging). The system provides users with a set of text communication file transfer, instant messaging platforms in one, basically meet the requirements of business users.Then, the paper of the instant messaging system server and client modules of the main components of a detailed analysis, discusses the detailed design of each module and implementation, respectively, described the main function of each module, and gives the module flow chart. Finally, the paper of the instant messaging system designed for server-side performance test, and test data were analyzed. Experimental data show that the system has easy to implement, reliable, scalable, and high transmission efficiency, achieved its design goals.Keywords: Instant Messaging, Socket, Communication Model, File Transfer目录1 绪论 (1)1.1课题背景 (1)1.2研究现状 (1)1.3研究意义 (2)1.4研究内容 (3)1.5论文结构 (3)1.6本章小结 (4)2 SOCKET相关技术研究 (5)2.1主流即时通信模型 (5)2.1.1 P2P模型 (5)2.1.2 C/S模型 (6)2.2即时通信主流的通信协议 (7)2.2.1 UDP协议 (7)2.2.2 TCP协议 (8)2.3S OCKET技术 (8)2.4多线程技术 (9)2.5JDBC技术 (10)2.6开发工具介绍 (11)2.6.1 Eclipse简介 (11)2.6.2 MySQL简介 (12)2.6.3 Visio简介 (13)2.7本章小结 (13)3 对SOCKET通信需求分析 (14)3.1即时通信系统总体需求 (14)3.2系统功能描述 (14)3.3系统协议的选定 (14)3.4系统设计性能分析 (15)3.5本章小结 (15)4实现SOCKET通信的方案和关键模块的设计 (16)4.1系统总体结构的描述 (16)4.1.1系统功能模块设计 (17)4.2服务器端工作流程 (19)4.2.1客户端工作流程 (21)4.3总体实现方案和类的设计 (22)4.4关键模块详细设计与实现 (23)4.4.1 利用Socket进行TCP连接 (23)4.4.2面向连接的Socket机制的模块设计 (27)4.5 文件传输模块 (28)4.6本章小结 (29)5 对程序进行调试与测试,并对结果进行分析 (30)5.1S OCKET通信的应用 (30)5.2聊天服务器端 (30)5.3聊天客户端 (32)5.4聊天系统的运行界面 (33)结论 (34)具体工作如下 (34)参考文献 (35)致谢 (37)附录A英语原文 (38)附录B汉语翻译 (53)1绪论即时通信(Instant Messaging)软件是我国目前上网用户使用率最高的软件之一,即时通信系统(Instant Messagin g System)可使人们在网上识别在线用户并与之实时交流。
socket实现ping命令的原理
socket实现ping命令的原理简介在计算机网络中,pi n g命令是一种用于测试两台主机之间网络连接性的常用工具。
本文将介绍使用so ck et编程实现p in g命令的原理。
什么是sock et?在网络通信中,s ock e t是一种通信机制,它可以使得不同计算机上的程序能够进行数据交换。
通过使用so ck et,我们可以实现不同计算机之间的网络连接和数据传输。
pin g命令的作用p i ng命令用于测试两台主机之间的网络连接性以及网络延迟。
它发送一条IC MP(I nt er ne t Co nt ro lM es sa geP r ot oc ol)回显请求消息到目标主机,并等待该主机返回回显应答消息。
通过这种方式,我们可以确定目标主机是否可达以及网络延迟的情况。
使用socke t编程实现pin g命令使用so ck et编程实现p in g命令需要以下几个步骤:步骤一:创建s o c k et首先,我们需要创建一个so ck et,用于与目标主机建立网络连接。
i m po rt so ck et创建一个IPv4的UDP socketc l ie nt_s oc ke t=soc k et.s oc ke t(so cke t.A F_IN ET,s oc ket.SO CK_ D G RA M)步骤二:设置超时时间为了避免长时间等待应答,我们可以设置一个超时时间。
当发送p in g请求后,如果在超时时间内未收到应答,我们可以认为网络连接存在问题。
设置超时时间为1秒钟c l ie nt_s oc ke t.set t im eo ut(1)步骤三:发送p i n g请求使用so ck et发送pi n g请求需要构建一个I CM P回显请求消息,并发送给目标主机。
i m po rt st ru ct构建ICMP回显请求消息ICMP回显请求ICMP Code为0填充校验和为0标识符(任意数值)序列号(任意数值)构建ICMP消息,计算校验和i c mp_h ea de r=st ruc t.p ac k('!BB HH H',i cm p_ty pe,i cm p_c o de,i cm p_c he ck su m,ic mp_i de nt if ie r,ic mp_s eq ue nc e)计算校验和更新校验和发送ping请求c l ie nt_s oc ke t.send to(i cm p_he ad er,(de st in at io n_ip,0))步骤四:接收应答接下来,我们需要等待目标主机的回应,并对回应消息进行解析。
编写socket通信程序课程设计
编写socket通信程序课程设计一、课程目标知识目标:1. 理解Socket通信的基本概念,掌握网络编程的相关知识;2. 学会使用Socket API编写客户端和服务器端通信程序;3. 了解网络协议(TCP/IP)的基本原理,并能在编程中正确应用;4. 掌握基本的异常处理和程序调试技巧。
技能目标:1. 能够独立设计并编写简单的Socket通信程序;2. 能够运用所学知识解决实际网络通信问题;3. 具备基本的网络编程调试能力,能对程序进行优化和改进;4. 提高学生的编程实践能力和问题解决能力。
情感态度价值观目标:1. 培养学生积极探索、勇于实践的精神,增强学生对网络编程的兴趣;2. 培养学生的团队协作意识,提高沟通与表达能力;3. 增强学生的网络安全意识,树立正确的网络道德观念;4. 使学生认识到编程知识在现代社会中的重要性,激发学生的学习热情。
课程性质:本课程为计算机网络编程的实践课程,旨在让学生通过动手实践,掌握网络编程的基本知识和技能。
学生特点:学生已具备一定的编程基础,熟悉C或Java等编程语言,对网络通信有一定的了解。
教学要求:结合学生特点,注重理论与实践相结合,以项目为导向,培养学生的实际编程能力和解决问题的能力。
在教学过程中,关注学生的个体差异,提供有针对性的指导,确保课程目标的达成。
通过课程学习,使学生能够独立完成Socket通信程序的编写和调试。
二、教学内容1. 网络编程基础知识- 网络协议(TCP/IP)原理- IP地址、端口号、域名解析等基本概念2. Socket编程基本概念- Socket的定义与作用- 套接字类型(流式套接字、数据报套接字等)- Socket API介绍3. 客户端与服务器端编程- 客户端程序设计方法- 服务器端程序设计方法- 客户端与服务器端通信流程4. 编程实践- 使用C或Java等编程语言实现Socket通信- 编写简单的聊天程序、文件传输程序等案例5. 异常处理与调试技巧- 常见异常类型及处理方法- 网络编程中的调试技巧6. 网络安全与网络道德- 网络安全基础知识- 网络道德规范教学内容安排与进度:第1周:网络编程基础知识,学习网络协议原理及基本概念第2周:Socket编程基本概念,了解Socket API及其使用方法第3周:客户端与服务器端编程,学习编程方法和通信流程第4周:编程实践,动手编写Socket通信程序第5周:异常处理与调试技巧,学习调试方法和优化程序第6周:网络安全与网络道德,提高网络安全意识和网络道德观念教学内容与教材关联性:本教学内容紧密结合教材,按照教材章节顺序进行组织和安排,确保学生能够系统地学习网络编程知识。
ping程序设计与实现课程设计
ping程序设计与实现课程设计一、课程目标知识目标:1. 学生能理解ping程序的工作原理,掌握网络诊断的基本方法。
2. 学生能描述IP协议、ICMP协议的基本概念及其在ping程序中的应用。
3. 学生了解计算机网络的通信原理,掌握如何利用ping程序检测网络连通性。
技能目标:1. 学生能运用所学知识,独立编写简单的ping程序。
2. 学生通过实践操作,提高问题分析及解决能力,具备基本的网络诊断技巧。
3. 学生掌握使用编程工具(如:IDE、编译器等)进行代码编写、调试和优化。
情感态度价值观目标:1. 学生培养对计算机网络的兴趣,激发学习编程的热情。
2. 学生在学习过程中,培养团队协作、沟通表达的能力,增强自信心。
3. 学生通过本课程的学习,认识到网络技术在实际应用中的重要性,培养对网络安全的责任感。
分析课程性质、学生特点和教学要求,本课程旨在让学生掌握ping程序的设计与实现,结合实际操作,提高学生的编程能力和网络诊断技巧。
课程目标具体、可衡量,有助于教师进行教学设计和评估。
通过本课程的学习,学生将具备基本的网络编程知识和技能,为今后的学习和工作打下坚实基础。
二、教学内容1. 网络基础知识回顾:IP协议、ICMP协议、网络层通信原理。
2. ping程序工作原理:发送ICMP请求、接收ICMP回复、计算往返时间(RTT)。
3. 编程语言基础:C语言或Python语言的基本语法,重点掌握数据类型、控制结构、函数定义。
4. ping程序设计与实现:- 环境搭建:安装编程工具、配置网络环境。
- 代码编写:根据ping程序工作原理,编写发送和接收ICMP请求的代码。
- 调试与优化:调试代码,处理异常情况,优化程序性能。
5. 实践操作:分组进行实际操作,组内讨论、分析问题,相互协作完成ping 程序编写。
6. 网络诊断技巧:运用ping程序检测网络连通性,分析网络延迟、丢包等问题。
教学内容安排和进度:第一课时:网络基础知识回顾,介绍ping程序工作原理。
c语言实现ping功能的例子
c语言实现ping功能的例子【最新版】目录1.概述2.Ping 功能原理3.C 语言实现 Ping 功能的步骤4.代码示例5.总结正文1.概述Ping 功能是网络诊断工具中非常常用的一个功能,它可以用来测试网络中两台主机之间是否可以正常通信,以及通信的延迟情况。
在众多的编程语言中,C 语言是一种非常适合进行网络编程的语言,其具有高效的性能和底层的控制能力。
本文将介绍如何使用 C 语言实现 Ping 功能。
2.Ping 功能原理Ping 功能的原理是发送一个 ICMP(Internet Control Message Protocol,互联网控制报文协议)数据包到目标主机,然后等待目标主机的响应。
发送的数据包包含一个 ICMP Echo Request 报文,目标主机收到请求后会返回一个 ICMP Echo Reply 报文。
发送方收到响应后,可以根据响应的时间和状态判断两台主机之间的网络通信情况。
3.C 语言实现 Ping 功能的步骤(1)包含必要的头文件:在 C 语言中实现 Ping 功能,需要包含<arpa/inet.h>、<netinet/in.h>、<netinet/ip.h>、<netinet/icmp.h>等头文件。
(2)构造 ICMP 数据包:使用 socket 函数创建一个 ICMP 套接字,然后使用 sendmsg 函数发送 ICMP Echo Request 报文。
(3)接收响应:使用 recvmsg 函数接收目标主机返回的 ICMP Echo Reply 报文。
(4)解析响应:根据接收到的 ICMP Echo Reply 报文中的信息,判断网络通信的状态和延迟情况。
c语言实现ping功能的例子
在C语言中,实现ping功能通常需要使用系统调用,因为ping命令本身就是一个系统调用。
下面是一个简单的例子:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <time.h>#define BUF_SIZE 256int main(int argc, char *argv[]) {if (argc != 2) {printf("Usage: %s <host>\n", argv[0]);exit(EXIT_FAILURE);}char *host = argv[1];struct hostent *he;struct sockaddr_in serv_addr;int sockfd = socket(AF_INET, SOCK_RAW, 0);if (sockfd < 0) {perror("socket");exit(EXIT_FAILURE);}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(ICMP_PORT); // use ICMP port number hereserv_addr.sin_addr.s_addr = inet_addr(host); // use inet_addr to convert IP string to binary formatif (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {perror("connect");exit(EXIT_FAILURE);}char packet[BUF_SIZE]; // packet to send to serverstruct icmphdr *icmp = (struct icmphdr *)packet; // the header of ICMP packeticmp->type = 8; // ICMP ECHO request (ping request)icmp->code = 0; // code of requesticmp->checksum = 0; // checksum of ICMP header and data, will be calculated automatically when sent to network layer icmp->un.echo.id = getpid() & 0xffff; // the ID of this ICMP request, use current process ID as the default valueicmp->un.echo.sequence = htons(1); // the sequence number of this ICMP request, start from 1 as the default valueint len = sizeof(struct icmphdr); // the length of ICMP header only, not including the data to be sent to server yetstrcpy(packet + len, "Hello World!"); // copy data to the end of ICMP packet, len is the length of data part of ICMP packet now, including the header and data togetherlen += strlen("Hello World!"); // update the length of data part of ICMP packet after adding dataicmp->checksum = icmp_cksum(packet, len); // calculate the checksum of ICMP header and data before sending it to network layer, and store the result in checksum field of ICMP header automatically when sent to network layer (at last)if (sendto(sockfd, packet, len, 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {perror("sendto");exit(EXIT_FAILURE);} else { // if sendto() is successful, then we can receive the response from server using recvfrom() here in this example code only, we will not receive any response in fact if we send a ping request to a server that does not exist or is not reachable (as in this example), we will receive an error message from network layer later (at last) if we send a ping request to a server that exists and is reachable, we will receive a response from server as soon as possible (normally within 1 second), and we can use recvfrom() to receive the response from server as shown in this example code here as well。
网络基础——socket的通信流程介绍,基于tcp协议通信的socket程序编写
⽹络基础——socket的通信流程介绍,基于tcp协议通信的socket程序编写⼀、socket的通信流程介绍⼀开始,套接字被设计⽤在同⼀台主机上多个应⽤程序之间的通讯。
这也被称进程间通讯,或 IPC。
套接字有两种(或者称为有两个种族),分别是基于⽂件型的和基于⽹络型的。
先从服务器端说起。
服务器端先初始化Socket,然后与端⼝绑定(bind),对端⼝进⾏监听(listen),调⽤accept阻塞,等待客户端连接。
在这时如果有个客户端初始化⼀个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建⽴了。
客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,⼀次交互结束.#socket()模块函数⽤法服务端套接字函数s.bind() 绑定(主机,端⼝号)到套接字s.listen() 开始TCP监听s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来客户端套接字函数s.connect() 主动初始化TCP服务器连接s.connect_ex() connect()函数的扩展版本,出错时返回出错码,⽽不是抛出异常公共⽤途的套接字函数s.recv() 接收TCP数据s.send() 发送TCP数据(send在待发送数据量⼤于⼰端缓存区剩余空间时,数据丢失,不会发完)s.sendall() 发送完整的TCP数据(本质就是循环调⽤send,sendall在待发送数据量⼤于⼰端缓存区剩余空间时,数据不丢失,循环调⽤send直到发完)s.recvfrom() 接收UDP数据s.sendto() 发送UDP数据s.getpeername() 连接到当前套接字的远端的地址s.getsockname() 当前套接字的地址s.getsockopt() 返回指定套接字的参数s.setsockopt() 设置指定套接字的参数s.close() 关闭套接字⾯向锁的套接字⽅法s.setblocking() 设置套接字的阻塞与⾮阻塞模式s.settimeout() 设置阻塞套接字操作的超时时间s.gettimeout() 得到阻塞套接字操作的超时时间⾯向⽂件的套接字的函数s.fileno() 套接字的⽂件描述符s.makefile() 创建⼀个与该套接字相关的⽂件⼆、基于tcp协议通信的套接字程序编写1、Socket是:应⽤层与TCP/IP协议族通信的中间软件抽象层,它是⼀组接⼝。
Linux网络编程基础(4)--Ping的C代码实现
Linux⽹络编程基础(4)--Ping的C代码实现1、背景 在进⾏⽹络编程的时候,通常使⽤的协议有TCP协议,UDP协议。
这些协议在简历套接字之初需要制定套接字的类型,⽐如TCP应当设置为 SOCK_STREAM,UDP对应的套接字应当设置为SOCK_DGRAM。
但是这些套接字并⾮能够提供⽹络所需的全部功能,我们还需要其他的套接字,⽐如原始套接字OCK_RAW。
原始套接字可以提供SOCK_STREAM和SOCK_DGRAM所不及的能⼒。
⽐如:(1)有了原始套接字,进程可以读取ICMPV4、ICMPV6、IGMP等的分组。
正如ping所使⽤的套接字,就是SOCK_RAW类型的。
这样使得使⽤ICMP和IGMP的程完全能够作为⽤户进程处理,⽽⽆需向内核添加代码。
(2)有了原始套接字,进程可以处理内核不处理其协议字段的IPV4数据报。
(3)有了原始套接字,进程使⽤IP_HDRINCL套接字选项定制⾃⼰的IPV4头部。
当然,上述的三个功能,并不是本⽂都要涉及的;只关注第⼀个能⼒,编写代码,实现ping程序。
2、基本使⽤ a.定义原始套接字与定义其他套接字没有形式上的巨⼤差别。
int sockfd; sockfd = socket(AF_INET, SOCK_RAW, protocol); protocol 的值是型为 IPPROTO_XXX的量,这些量定义在<netinet/in.h>中,⽐如ping使⽤的 IPPROTO_ICMP(关于IPV6的实现,再后续补充)。
只有超级⽤户才可以创建SOCK_RAW类型的套接字。
b. 原始套接字并不存在端⼝的概念。
可以在原始套接字上调⽤bind函数,但是这么做并不常见。
bind函数会设置发送数据报的源IP地址,如果没有使⽤ bind函数,那么内核将出发的借⼝地址作为源地址。
c. 同样,⼀般不会使⽤connect函数,connect函数会指定⽬的地址,但是因为原始套接字不存在端⼝概念,所以connect函数并不重要了。
ping源代码
PING程序的设计一、实验目的PING程序是我们使用的比较多的用于测试网络连通性的程序。
PING程序基于ICMP,使用ICMP的回送请求和回送应答来工作。
由计算机网络课程知道,ICMP是基于IP的一个协议,ICMP包通过IP的封装之后传递。
课程设计中选取PING程序的设计,其目的是希望同学们通过PING程序的设计,能初步掌握TCP/IP网络协议的基本实现方法,对网络的实现机制有进一步的认识。
二、实验内容和要求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 ΧΧΧ.ΧΧΧ.ΧΧΧ.ΧΧΧ或REQUEST TimeOut (无法PING通的情况)。
三、实验主要仪器设备和材料联网计算机。
四、实验方法、步骤及结构测试实验按下述步骤进行:1) 熟悉IP以及ICMP协议的工作机制2) 熟悉RAW模式的SOCKET编程3) 编写PING的实现程序4) 编译环境中需要包括SOCKET库 WS2_32.lib5) 在模拟实现环境下调试并运行自己编写的PING程序六、应收集的资料及主要参考文献1. 程良伦主编,《网络工程概论》,机械工业出版社. 20072. 苏峰,黄金双,汤蕾编著,《Visual C++.NET编程实例》,清华大学出版社.20043. 黄嘉辉编著,《Internet与TCP/IP程序设计之C++ Builder高手》,清华大学出版社.2001PING程序的设计ping核心程序void Ping(LPCSTR pstrHost){SOCKET rawSocket;LPHOSTENT lpHost;sockaddr_in saDest;sockaddr_in saSrc;DWORD dwTimeSent;DWORD dwElapsed;u_char cTTL;int nLoop;int nRet;//创建一个原始套接口rawSocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);if(rawSocket==SOCKET_ERROR){ReportError("socket()");return;}//根据主机名查询主机地址lpHost=gethostbyname(pstrHost);if(lpHost==NULL){fprintf(stderr,"\nHost not found:%s\n");return;}//设置目标套接口地址saDest.sin_addr.s_addr=*((u_long FAR*)(lpHost->h_addr)); saDest.sin_family=AF_INET;saDest.sin_port=0;//输出Ping程序的提示信息printf("\nPinging %s [%s] with %d bytes of data:\n",pstrHost,inet_ntoa(saDest.sin_addr),REQ_DATASIZE);//控制Ping执行的次数for(nLoop=0;nLoop<4;nLoop++){SendEchoRequest(rawSocket,&saDest);//使用select()等待接收回送的数据 nRet=WaitForEchoReply(rawSocket);if(nRet==SOCKET_ERROR){ReportError("select()");break;}if(!nRet){printf("\nTimeOut");//输出超时提示break;}//接收应答dwTimeSent=RecvEchoReply(rawSocket,&saSrc,&cTTL);//计算传输时间dwElapsed=GetTickCount()-dwTimeSent;printf("\nReply from:%s:bytes=%d time =%ld ms TTL=%d",inet_ntoa(saSrc.sin_addr),REQ_DATASIZE,dwElapsed,cTTL);printf("\n");}nRet=closesocket(rawSocket);if(nRet==SOCKET_ERROR){ReportError("closesocket()");}}//////////////////////////////////////////////////////////////////////// ////////////////////////int SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)//给目标站点发送回送请求{static ECHOREQUEST echoReq;static int nRet;//填写回送请求信息echoReq.icmpHdr.Type=ICMP_ECHOREQ;echoReq.icmpHdr.Code=0;echoReq.icmpHdr.Checksum=0;echoReq.icmpHdr.ID=nId++;echoReq.icmpHdr.Seq=nSeq++;//填写要发送的数据for(nRet=0;nRet<REQ_DATASIZE;nRet++)echoReq.cData[nRet]=' '+nRet;//保存发送时间echoReq.dwTime=GetTickCount();//数据存入包中并计算检验和echoReq.icmpHdr.Checksum=in_cksum((u_short*)&echoReq,sizeof(ECHOREQUEST) );//发送回送请int nAddrLen=sizeof(struct sockaddr_in);nRet=sendto(s,(LPSTR)&echoReq,sizeof(ECHOREQUEST),0,(LPSOCKADDR)lpstToAd dr,nAddrLen);if(nRet==SOCKET_ERROR)ReportError("sendto()");return(nRet);}//接收数据并对字段进行分析DWORD RecvEchoReply(SOCKET s,LPSOCKADDR_IN lpsaFrom,u_char *pTTL){ECHOREPLY echoReply;int nRet;int nAddrLen=sizeof(struct sockaddr_in);//接收回送应答nRet=recvfrom(s,(LPSTR)&echoReply,sizeof(ECHOREPLY),0,(LPSOCKADDR)lpsaFr om,&nAddrLen);检查返回值if(nRet==SOCKET_ERROR)ReportError("recvform()");*pTTL=echoReply.ipHdr.TTL;//返回发送时间的IP生存时间TTLreturn(echoReply.echoRequest.dwTime);}//输出发生的错误void ReportError(LPCSTR pWhere){fprintf(stderr,"\n error:%d\n",WSAGetLastError());}//使用select()函数进行状态查询,以确定是否有数据等待读取 int WaitForEchoReply(SOCKET s){struct timeval Timeout;fd_set readfds;readfds.fd_count=1;readfds.fd_array[0]=s;_sec=5;_usec=0;register u_short answer;register int sum=0;while(nleft>1){sum+=*w++;nleft-=2;}if(nleft==1){u_short u=0;*(u_char*)(&u)=*(u_char*)w;sum+=u;}sum=(sum>>16)+(sum&0xffff);sum+=(sum>>16);answer=~sum;return(answer);}PING程序的设计|网络概论课程设计报告|报告ping实验结果在命令行输入如下信息,进行本机测试:>Ping 127.0.0.1输出结果为:如果输入:>Ping 输出结果为:如果输入:>Ping 192.168.1.168输出结果为:5 总结本次课程设计较好地实现了要求做到的功能,但同时也遇到了不少的困难和挑战。
python实现一个简单的ping工具方法
python实现⼀个简单的ping⼯具⽅法继上⼀篇计算checksum校验和,本章通过套接字,字节打包成⼆进制,返回套接字的⽂件描述符的结合,实现⼀个简单的ping⼯具。
#!/usr/bin/python3.6.4#!coding:utf-8__author__ = 'Rosefinch'__date__ = '2018/5/31 22:27'import timeimport structimport socketimport selectimport sysdef chesksum(data):"""校验"""n = len(data)m = n % 2sum = 0for i in range(0, n - m ,2):sum += (data[i]) + ((data[i+1]) << 8)#传⼊data以每两个字节(⼗六进制)通过ord转⼗进制,第⼀字节在低位,第⼆个字节在⾼位if m:sum += (data[-1])#将⾼于16位与低16位相加sum = (sum >> 16) + (sum & 0xffff)sum += (sum >> 16) #如果还有⾼于16位,将继续与低16位相加answer = ~sum & 0xffff#主机字节序转⽹络字节序列(参考⼩端序转⼤端序)answer = answer >> 8 | (answer << 8 & 0xff00)return answer'''连接套接字,并将数据发送到套接字'''def raw_socket(dst_addr,imcp_packet):rawsocket = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket.getprotobyname("icmp"))send_request_ping_time = time.time()#send data to the socketrawsocket.sendto(imcp_packet,(dst_addr,80))return send_request_ping_time,rawsocket,dst_addr'''request ping'''def request_ping(data_type,data_code,data_checksum,data_ID,data_Sequence,payload_body):#把字节打包成⼆进制数据imcp_packet = struct.pack('>BBHHH32s',data_type,data_code,data_checksum,data_ID,data_Sequence,payload_body)icmp_chesksum = chesksum(imcp_packet)#获取校验和imcp_packet = struct.pack('>BBHHH32s',data_type,data_code,icmp_chesksum,data_ID,data_Sequence,payload_body)return imcp_packet'''reply ping'''def reply_ping(send_request_ping_time,rawsocket,data_Sequence,timeout = 2):while True:started_select = time.time()what_ready = select.select([rawsocket], [], [], timeout)wait_for_time = (time.time() - started_select)if what_ready[0] == []: # Timeoutreturn -1time_received = time.time()received_packet, addr = rawsocket.recvfrom(1024)icmpHeader = received_packet[20:28]type, code, checksum, packet_id, sequence = struct.unpack(">BBHHH", icmpHeader)if type == 0 and sequence == data_Sequence:return time_received - send_request_ping_timetimeout = timeout - wait_for_timeif timeout <= 0:return -1'''实现 ping 主机/ip'''def ping(host):data_type = 8 # ICMP Echo Requestdata_code = 0 # must be zerodata_checksum = 0 # "...with value 0 substituted for this field..."data_ID = 0 #Identifierdata_Sequence = 1 #Sequence numberpayload_body = b'abcdefghijklmnopqrstuvwabcdefghi' #datadst_addr = socket.gethostbyname(host)#将主机名转ipv4地址格式,返回以ipv4地址格式的字符串,如果主机名称是ipv4地址,则它将保持不变print("正在 Ping {0} [{1}] 具有 32 字节的数据:".format(host,dst_addr))for i in range(0,4):icmp_packet = request_ping(data_type,data_code,data_checksum,data_ID,data_Sequence + i,payload_body)send_request_ping_time,rawsocket,addr = raw_socket(dst_addr,icmp_packet)times = reply_ping(send_request_ping_time,rawsocket,data_Sequence + i)if times > 0:print("来⾃ {0} 的回复: 字节=32 时间={1}ms".format(addr,int(times*1000)))time.sleep(0.7)else:print("请求超时。
Ping命令实现
课程实践报告一.任务描述二.工作基础Socket接口是TCP/IP网络的API,它包含许多函数,用来支持进程间通信Socket译成“套接字”,应用进程要想利用这套函数通信,必须将自己关联到一个套接字上。
–电话系统的插座–邮政系统的邮箱是可以被命名和寻址的通信端点–IP地址+端口号TCP/IP的Socket有三种类型(1)流式套接字(SOCK_STREAM):提供面向连接的、可靠的数据传输服务。
这种服务保证数据按照发送顺序正确到达接收方。
但要像打电话一样的使用。
(2)数据报式套接字(SOCK_DGRAM):提供无连接的、不可靠的数据传输服务,使用方式类似于邮政,数据可能丢失、重复或顺序混乱。
(3)原始套接字(SOCK_RAW):该接口允许对较低层协议(如IP,ICMP)直接访问。
三.程序设计由上面的执行结果可以看到,ping命令执行后显示出被测试系统主机名和相应IP地址、返回给当前主机的ICMP报文顺序号、ttl生存时间和往返时间rtt(单位是毫秒,即千分之一秒)。
要写一个模拟ping命令,这些信息有启示作用。
要真正了解ping命令实现原理,就要了解ping命令所使用到的TCP/IP协议。
ICMP(Internet Control Message,网际控制报文协议)是为网关和目标主机而提供的一种差错控制机制,使它们在遇到差错时能把错误报告给报文源发方。
ICMP协议是IP层的一个协议,但是由于差错报告在发送给报文源发方时可能也要经过若干子网,因此牵涉到路由选择等问题,所以ICMP报文需通过IP协议来发送。
ICMP数据报的数据发送前需要两级封装:首先添加ICMP报头形成ICMP报文,再添加IP报头形成IP数据报。
由于IP层协议是一种点对点的协议,而非端对端的协议,它提供无连接的数据报服务,没有端口的概念,因此很少使用bind()和connect()函数,若有使用也只是用于设置IP地址。
1.头文件和定义函数以及变量2.计算发送和接收的时间3.统计数据结果4.校验和函数5.ICMP头部校验打包和拆包6.计算时间差函数7.发送报文函数8.接收目的主机的回复函数9.设置ICMP头部10.设计主函数四.程序实现五.总结在生活中,一旦断网,相信很多人第一件事就是调出终端,ping一下自己的路由,当然大多数是ping一下百度。
使用socket编程实现不同主机之间的通信进程设计心得
使用socket编程实现不同主机之间的通信进程设计心得1. 引言1.1 概述在现代网络通信领域中,实现不同主机之间的通信进程是一项核心任务。
为了满足各种需求,socket编程成为一种常用的实现方式。
通过socket编程,可以建立起客户端和服务器端之间的连接,实现数据传输和通信。
1.2 文章结构本文共分为五个部分进行阐述。
引言部分将对文章内容进行概括和介绍。
第二部分将简要介绍socket编程的概念和应用领域,并探讨不同主机之间通信的需求。
第三部分将详细阐述使用socket编程进行通信进程设计时需要考虑的客户端和服务器端角色划分、连接建立和断开流程设计以及数据传输协议设计与实现等问题。
第四部分则总结了遇到的问题以及相应解决方案,包括网络环境不稳定导致的连接中断问题、安全性与加密问题以及大规模并发连接处理问题。
最后一部分是结论与展望,对文章进行总结,并提出设计心得体会和改进建议,并展望未来网络通信发展趋势和技术。
1.3 目的本文旨在探索使用socket编程实现不同主机之间的通信进程设计。
通过深入分析socket编程的概念和应用场景,以及客户端和服务器端角色划分、连接建立和断开流程设计以及数据传输协议设计与实现等关键问题,可以帮助读者更好地理解并掌握socket编程的核心要点。
同时,总结遇到的问题与解决方案,并提出改进建议,旨在为读者在实际应用中遇到类似问题时提供参考。
最后,通过对未来网络通信发展趋势和技术的思考,展望socket编程在日益发展的网络领域中的应用前景和挑战。
2. socket编程概述:2.1 socket编程简介:Socket编程是一种用于实现不同主机之间通信的计算机网络编程技术。
它基于计算机网络中的传输层协议(如TCP或UDP),通过套接字(Socket)接口在不同主机间建立连接并进行数据传输。
通过使用Socket库函数,我们可以创建、配置和管理套接字,以便进行有效且可靠的数据交换。
2.2 不同主机之间通信的需求:在计算机网络中,不同主机之间的通信需要通过适当的协议和技术来实现。
编程模拟PING程序
编程模拟ping程序一、实习题目编程模拟Ping程序,要求实现Ping程序的基本功能即可,即接收到一个Ping数据包后给出回应。
二、原理概述Ping程序是用来探测主机与主机之间是否可通信,如果不能Ping到某台主机,表明不能和这台主机建立连接。
Ping的原理就是首先建立通道,然后发送数据包,对方接受后返回信息,这个数据包包括对方的IP地址和自己的地址,还有序列数,回送的报文包括双方地址,还有时间等。
网络上的机器都有唯一确定的IP地址,我们给目标IP地址发送一个数据包,对方就要返回一个同样大小的数据包,根据返回的数据包我们可以确定目标主机的存在,可以初步判断目标主机的操作系统等。
Ping使用的是ICMP协议,它发送ICMP回送请求消息给目的主机。
ICMP协议是过IP协议发送的,IP协议是一种无连接的,不可靠的数据包协议。
因此,保证数据送达的工作应该由其他的模块来完成。
其中一个重要的模块就是ICMP 协议。
当发送的IP数据包发生错误—比如主机不可达,路由不可达等等,ICMP 协议将会把错误信息封装,然后传送会给主机。
Ping利用ICMP协议包来侦测另一个主机是否可达,原理是用类型码为0的ICMP发请求,收到请求的主机则用类型码为8的ICMP回应。
Ping程序来计算间隔时间,并计算有多少个包被发送,用户就可判断网络大致的情况。
IP头与ICMP头的设置分别参照RFC791及RFC792的标准,包含所有必要信息。
ICMP回送数据结构增加了数据传输时间用于计算。
主程序设置PING()函数,用于数据包发送及接收。
由于发送数据包时可能会遇到阻塞或者目标主机不通,造成超时,因此需要在发送数据包后调用一个函数来判断是否超时,此处设置一个函数来实现超时判断功能,该函数调用SOCKET的select()来进行判断。
其次,还需要一个函数来计算CRC校验和,校验和采用移位的方法进行计算。
另外设置一函数来返回SOCKET操作相关的错误代码。
PING程序原理及实现
PING程序原理及实现
一、原理:
Ping命令的工作原理是:向网络上的另一个主机系统发送ICMP报文,如果指定系统得到了报文,它将把报文一模一样地传回给发送者。
Ping的时候发送的ICMP报文类型为8,系统回复的报文类型为0,报文中包含的数据不变。
在发送的时候,我们可以将现在的系统时间作为ICMP的报文数据发出。
接收到回复报文后,可以读取ICMP 报文的数据得到发送的时间,与现在的时间对比可以得到系统的响应时间。
二、程序具体实现:
1)根据IP报文头结构和ICMP报文头结构定义相应的数据结构,然后用定义的数据结构声明要发送
的数据Send和接受数据Recive,并初始化发送数据Send。
将发送的数据Send的ICMP的类型设置为8。
2)声明一个sockaddr_in类型的变量,将其地址设置为目的地的IP地址。
并声明一个
SOCKET类型的成员变量,用来接收和发送ICMP数据。
3)在窗口初始化函数中设置一个时钟,在该时钟的响应函数中发送和接收数据包,并刷
新显示窗口。
4)在发送函数中调用sendto函数发送数据,然后调用select函数监听该SOCKET。
如果在
指定时间内没有监听到数据,则在窗口显示超时;如果有数据,则调用接收函数,分析接收的数据,从中提取发送时间并与现在的时间做对比,得到相应时间。
socket心跳包与ping命令
PingOptions myOptions = new PingOptions();
myOptions.DontFragment = true;
PingReply myPingReply = myPing.Send(ip, 300, buff, myOptions);
if (myPingReply.Status == IPStatus.Success)
{
}
else
{
continue;
}
以上代码的作用就是设置tcp心跳为5秒当三次检测到无法与客户端连接后将会关闭socket
socket心跳包与ping命令
C#编程环境下socket通信的心跳包程序
// 假设 accepted 到的 Socket 为变量 client
...
// 设置 TCP 心跳,空闲 15 秒,每 5 秒检查一次
byte[] inOptionValues = new byte[4 * 3];
BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0);
BitConvtionValues, 4);
BitConverter.GetBytes((uint)5000).CopyTo(inOptionValues, 8);
IPAddress ip = ((.IPEndPoint)s2.RemoteEndPoint).Address;
string data = "abcdefghijklmnopqrstuvwxy123456";
byte[] buff = Encoding.ASCII.GetBytes(data);
ping的实现课程设计
ping的实现 课程设计一、课程目标知识目标:1. 理解ping命令的基本工作原理,掌握其网络诊断功能;2. 学习并掌握使用ping命令检测网络连通性的方法;3. 了解ping命令的参数设置及其作用。
技能目标:1. 学会运用ping命令进行简单的网络故障排查;2. 能够通过ping命令的结果,分析网络延迟、丢包等问题;3. 培养学生对网络故障的敏感度,提高解决问题的能力。
情感态度价值观目标:1. 培养学生对计算机网络知识的兴趣,激发探索精神;2. 培养学生团队合作意识,学会在网络环境中与他人共同解决问题;3. 强化网络安全意识,让学生明白网络诊断工具的正确使用方法。
课程性质:本课程为计算机网络基础课程,旨在帮助学生掌握网络诊断的基本方法,提高实际操作能力。
学生特点:学生为初中年级,对计算机网络知识有一定的了解,具备基本的计算机操作能力。
教学要求:通过本章节的学习,要求学生能够熟练运用ping命令进行网络诊断,并具备一定的网络故障排查能力。
将目标分解为具体的学习成果,以便后续的教学设计和评估。
二、教学内容1. 理论知识:- 计算机网络基础知识回顾,重点强调TCP/IP协议;- ping命令的工作原理,介绍ICMP协议的作用;- ping命令的参数及其功能解释,如:-t、-a、-n、-l等。
2. 实践操作:- 演示如何使用ping命令检测网络连通性;- 指导学生使用ping命令检测本地网络中的设备;- 实践案例:分析ping命令返回结果,判断网络延迟、丢包等问题。
3. 教学大纲:- 第一课时:计算机网络知识回顾,介绍ping命令及其工作原理;- 第二课时:ping命令的参数介绍,演示如何使用ping命令;- 第三课时:实践操作,学生分组进行网络诊断,分析ping命令结果;- 第四课时:总结与拓展,讨论网络故障排查的其他方法,强化网络安全意识。
教材关联:教学内容与课本第三章“网络诊断与故障排除”相关,结合课本案例,使学生更好地掌握网络诊断技巧。
corundumstudio.socketio pingpong机制
corundumstudio.socketio pingpong机制CorundumStudio.SocketIO PingPong 机制Socket.IO 是一个基于事件驱动的实时通信库,用于构建跨平台的实时应用程序。
它使用了一种称为 PingPong 机制的技术,以确保客户端和服务器之间的连接保持稳定和可靠。
I. 机制概述PingPong 机制是 Socket.IO 中使用的一项重要技术,旨在测试和维持客户端与服务器之间的连接。
Ping 指的是服务器向客户端发送的信号,而Pong 则是客户端向服务器回复的信号。
通过定期交换这些信号,可以识别潜在的连接问题并采取相应的措施。
II. 机制原理在 Socket.IO 中,服务器周期性地向客户端发送 Ping 消息,并设置一个超时时间。
客户端接收到该消息后,立即回复一个 Pong 消息给服务器。
如果服务器在超时时间内收到了 Pong 消息,表示连接正常;否则,服务器将认为连接已经断开,并触发相应的事件处理程序。
III. 机制实现为了实现 PingPong 机制,首先需要在服务器端设置 Ping 消息的发送频率和超时时间。
可以根据实际需求调整这些参数,以获得最佳的连接保持效果。
同时,在客户端也需要相应地设置 Pong 消息的回复时间,确保能够及时响应服务器的 Ping 消息。
IV. 机制优化为了提高PingPong 机制的效率和稳定性,可以考虑以下优化措施:1. 调整 PingPong 间隔时间:根据网络延迟和实时性要求,调整PingPong 消息的发送间隔,避免过于频繁或过于稀疏。
2. 基于心跳检测:除了基本的 PingPong 机制,可以采用心跳检测的方式,通过互相发送心跳信号来进一步监测连接状态。
3. 断线重连机制:当客户端或服务器检测到连接断开时,可以尝试重新建立连接,以确保持续的通信。
V. 机制应用PingPong 机制广泛应用于各种需要实时通信的场景,例如在线游戏、聊天应用和实时数据传输等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机科学与技术学院课程设计成绩单优秀:90分~100分良好:80分~89分中等:70~79分及格:60~69分不及格0分~59分武汉科技大学计算机科学与技术学院制表计算机科学与技术学院课程设计报告课程名称:计算机网络专业: xxxxxxxx 班级: xxxx级 xx 班学号: 20xxxxxxxxxx 姓名: xxxxxxx 指导老师: xxxxxxxx概要设计1.1题目的内容与要求题目内容:PING程序是我们使用的比较多的用于测试网络连通性的程序。
PING程序基于ICMP,使用ICMP的回送请求和回送应答来工作。
其中,ICMP 是基于IP的一个协议,ICMP包通过IP的封装之后传递。
PING程序是面向用户的应用程序,该程序使用ICMP的封装机制,通过IP协议来工作。
为了实现直接对IP和ICMP包进行操作,实验中使用SOCKET编程机制。
设计要求:1、SOCKET编程熟悉SOCKET的编程,包括基本的系统调用如SOCKET、BIND等。
2、具体内容1) 定义数据结构需要定义好IP数据报、ICMP包等相关的数据结构2) 程序实现在WINDOWS环境下实现PING程序3) 程序要求在命令提示符下输入:PING ΧΧΧ.ΧΧΧ.ΧΧΧ.ΧΧΧ其中ΧΧΧ为目的主机的IP地址,不要求支持域名,对是否带有开关变量也不做要求。
不带开关变量时,要求返回4次响应。
返回信息的格式:REPL Y FROM ΧΧΧ.ΧΧΧ.ΧΧΧ.ΧΧΧ或REQUEST TimeOut (无法PING通的情况)4)编程语言不限。
需求分析和详细设计2.1Ping主模块Ping()函数是本程序的核心部分,它基本是调用其他模块的函数来实现最终功能,其主要布骤包括:定义及初始化各个全局变量、打开socket动态库、设置接收和发送超时值、域名地址解析、分配内存、创建及初始化ICMP报文、发送ICMP 请求报文、接收ICMP 应答报文以及解读应答报文和输出Ping结果,最后释放占用的资源其流程如下页图2.1所示。
注释:(1)该模块并非只有处理还包括判断及输出判断结果的含义;(2)程序没运行一次就只能输出四行结果(前提是输入的地址有效),欲再次PING其他地址必须要重新启动程序。
(3)输入时不能输入目标主机名,不然ping结果为TIMEOUT;图2.1 主模块流程图2.2功能控制模块功能控制模块主要是为其他模块提供可调用的函数,该模块主要包括参数获取功能、计算ICMP 数据报文检验和、清除SOCKET,ICMP 包数据以及接受缓冲区、占用资源释放功能和显示用尸帮助功能。
该模块一共包含三个函数来实现。
,流程如图2.2所示。
图2.2 功能控制模块注释:(1) illICMPData 是由一系列的初始化的语句在流程图中不再画出;(2)Cleanup() 函数中的WSACleanup(),HeapFree(),closesocket()都是一些库函数。
(3)checksum()校验和函数是冗余校验的一种形式。
它是通过错误检测方法,对经过空间(如通信)或者时间(如计算机存储)传送的数据的完整性进行检查的一种简单方法。
2.3数据报解析模块数据报解析模块提供了解读IP选项和解读IcMP报文的功能。
从本机收到目的主机返回的1cMP回显应答报文,就开始逐个地解读IcMP报文,如果需要记录路由的情况下,IcMP解析函数将调用IP选项解读函数来实现IP路由的输出(但本程序没有此功能。
该模块主要由DecodeICMPHeader一个函数来实现,而中间也会调用其它模块的相应函数。
其流程图如图2.3:注释:(1)判断是否为我们所要的数据报回应之前,还有一些判断回应多少内容的语句未呈现出;(2)函数GetTickCount()是用来记录此时我机所处的现在时间(毫秒级);图2.3 数据报解析模块运行界面运行操作及结果:在VC中运行程序后会出现如图4.1所示,提示你输入IP或网址;图4.1开始输入下面我们先以输入室友的IP地址为例进行试验,结果如图4.2;图4.2测试本地IP接着我们任意输入网络地址,在联网的情况下,结果如图4.3;图4.3测试网络IP 但是当断开网络连接时时,就会出现下图结果:图4.网络IP不通附录(程序清单)#pragma comment(lib,"ws2_32.lib")#include <winsock2.h>#include <ws2tcpip.h>#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct _iphdr{unsigned int h_len:4; // 头长度unsigned int version:4; // IP版本unsigned char tos; // 服务类型unsigned short total_len; // 包的总长度unsigned short ident; // 包标示身份unsigned short frag_and_flags; // 标志unsigned char ttl; // 包生命周期unsigned char proto; // 协议类型unsigned short checksum; // IP 校验unsigned int sourceIP;//源IPunsigned int destIP;//目标IP} IpHeader;#define ICMP_ECHO 8#define ICMP_ECHOREPL Y 0#define ICMP_MIN 8 // 最小8字节的包头typedef struct _icmphdr{BYTE i_type;BYTE i_code;USHORT i_cksum;USHORT i_id;USHORT i_seq;// 为世间留空间ULONG timestamp;//时间戳} IcmpHeader;#define DEF_PACKET_SIZE 32#define MAX_PACKET 1024 // 最大ICMP 包长度#define MAX_IP_HDR_SIZE 60 // 最大IP头长度int datasize=DEF_PACKET_SIZE;char *icmp_data=NULL;char *recvbuf=NULL;SOCKET m_hSocket= INV ALID_SOCKET;char *lpdest=NULL;void FillICMPData(char *icmp_data, int datasize){IcmpHeader *icmp_hdr = NULL;char *datapart = NULL;icmp_hdr = (IcmpHeader*)icmp_data;icmp_hdr->i_type = ICMP_ECHO; // 要求有IP回应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);}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 & 0xffff);cksum += (cksum >>16);return (USHORT)(~cksum);}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;iphdrlen = iphdr->h_len * 4;tick = GetTickCount();if (bytes < iphdrlen + ICMP_MIN){printf("Too few bytes from %s \r\n",inet_ntoa(from->sin_addr));}icmphdr = (IcmpHeader*)(buf + iphdrlen);if (icmphdr->i_type != ICMP_ECHOREPL Y){printf("nonecho type %d recvd \r\n", icmphdr->i_type);return;}// 确定是我们发的数据包回应if (icmphdr->i_id != (USHORT)GetCurrentProcessId()){printf("其他程序的回应报文! \t错误代码%d\n",WSAGetLastError());return ;}DWORD tick0[4];tick0[icmpcount]=tick - icmphdr->timestamp;if(tick0[icmpcount]<1)printf("Reply from %s: bytes=%d time<1ms icmp_seq = %d\n",inet_ntoa(from->sin_addr), bytes, icmphdr->i_seq );else printf("Reply from %s: bytes=%d time=%dms icmp_seq = %d\n",inet_ntoa(from->sin_addr), bytes,tick0[icmpcount], icmphdr->i_seq);icmpcount++;return;}void Cleanup(){if (m_hSocket != INV ALID_SOCKET)closesocket(m_hSocket);HeapFree(GetProcessHeap(), 0, recvbuf);HeapFree(GetProcessHeap(), 0, icmp_data);WSACleanup();return ;}void main(){WSADATA wsaData;char a[100];printf("ping ");scanf("%s",a);lpdest=a;SOCKADDR_IN m_addrDest;SOCKADDR_IN m_addrFrom;int timeout=1000;USHORT seq_no=0;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){printf("Sorry, you cannot load socket dll!");}m_hSocket = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,WSA_FLAG_OVERLAPPED);if (m_hSocket == INV ALID_SOCKET){printf("socket 创建失败!");}int bread = setsockopt(m_hSocket, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(timeout));if(bread == SOCKET_ERROR){printf("设置socket接收超时选项错误!");}timeout = 1000;bread = setsockopt(m_hSocket, SOL_SOCKET, SO_SNDTIMEO,(char*)&timeout, sizeof(timeout));if (bread == SOCKET_ERROR){printf("设置socket发送超时选项错误!");}memset(&m_addrDest, 0, sizeof(m_addrDest));// 如果必要的话需要对输入IP进行解析m_addrDest.sin_family = AF_INET;if ((m_addrDest.sin_addr.s_addr = inet_addr(lpdest)) == INADDR_NONE){struct hostent *hp = NULL;if ((hp = gethostbyname(lpdest)) != NULL){memcpy(&(m_addrDest.sin_addr), hp->h_addr, hp->h_length);m_addrDest.sin_family = hp->h_addrtype;}else{printf("不能找到名为%s 的主机\t错误代码%d\n",lpdest, WSAGetLastError());exit(0);}}printf("Pinging %s with 64 bytes of data: \n\n", inet_ntoa(m_addrDest.sin_addr));// 创建ICMP包datasize += sizeof(IcmpHeader);icmp_data =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PACKET);recvbuf =(char*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,MAX_PACKET);if (!icmp_data){printf("堆分配错误!");}memset(icmp_data,0,MAX_PACKET);FillICMPData(icmp_data,datasize);// 开始发送或接受ICMP包int nCount=0;while(1){int bwrote;if (nCount++ == 4)break;((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);bwrote = sendto(m_hSocket, icmp_data, datasize, 0,(struct sockaddr*)&m_addrDest, sizeof(m_addrDest));if (bwrote == SOCKET_ERROR){if (WSAGetLastError() == WSAETIMEDOUT){printf("Requrest timed out ! \r\n");continue;}printf("目标不可达!\t错误代码%d\n", WSAGetLastError());continue;}if (bwrote < datasize){printf("Wrote %d bytes \r\n", bwrote);}int fromlen = sizeof(m_addrFrom);bread = recvfrom(m_hSocket, recvbuf, MAX_PACKET, 0,(struct sockaddr*)&m_addrFrom, &fromlen);if (bread == SOCKET_ERROR){if (WSAGetLastError() == WSAETIMEDOUT){printf("Requrest timed out !\r\n");continue;}printf("接收数据函数调用错误!\t错误代码%d\n", WSAGetLastError());exit(0);}DecodeICMPHeader(recvbuf, bread, &m_addrFrom);}Cleanup();}。