做网站的人月,海口模板网站建站,温州模板建站代理,网站如何上传数据库From: http://www.linuxidc.com/Linux/2012-05/61073.htm ICMP是#xff08;Internet Control Message Protocol#xff09;Internet控制报文协议。它是TCP/IP协议族的一个子协议#xff0c;用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路…From: http://www.linuxidc.com/Linux/2012-05/61073.htm ICMP是Internet Control Message ProtocolInternet控制报文协议。它是TCP/IP协议族的一个子协议用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据但是对于用户数据的传递起着重要的作用。 ICMP协议是一种面向无连接的协议用于传输出错报告控制信息。它是一个非常重要的协议它对于网络安全具有极其重要的意义。 折腾半天原来ICMP也是TCP/IP其中一种协议.那么监测网络是否ping的通就跟TCP协议差不多了。 步骤简单归纳为1.绑定套接字2.发送数据包 3.接收数据包 4.解析数据包 #include stdio.h #include sys/socket.h #include netinet/in.h #include netinet/ip.h #include netinet/ip_icmp.h #include netdb.h #define PACKET_SIZE 4096 #define ERROR 0 #define SUCCESS 1 //效验算法百度下有注释但是还是看不太明白 unsigned short cal_chksum(unsigned short *addr, int len) { int nleftlen; int sum0; unsigned short *waddr; unsigned short answer0; while(nleft 1) { sum *w; nleft - 2; } if( nleft 1) { *(unsigned char *)(answer) *(unsigned char *)w; sum answer; } sum (sum 16) (sum 0xffff); sum (sum 16); answer ~sum; return answer; } // Ping函数 int ping( char *ips, int timeout) { struct timeval *tval; int maxfds 0; fd_set readfds; struct sockaddr_in addr; struct sockaddr_in from; // 设定Ip信息 bzero(addr,sizeof(addr)); addr.sin_family AF_INET; addr.sin_addr.s_addr inet_addr(ips); int sockfd; // 取得socket sockfd socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sockfd 0) { printf(ip:%s,socket error\n,ips); return ERROR; } struct timeval timeo; // 设定TimeOut时间 timeo.tv_sec timeout / 1000; timeo.tv_usec timeout % 1000; if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, timeo, sizeof(timeo)) -1) { printf(ip:%s,setsockopt error\n,ips); return ERROR; } char sendpacket[PACKET_SIZE]; char recvpacket[PACKET_SIZE]; // 设定Ping包 memset(sendpacket, 0, sizeof(sendpacket)); pid_t pid; // 取得PID作为Ping的Sequence ID pidgetpid(); struct ip *iph; struct icmp *icmp; icmp(struct icmp*)sendpacket; icmp-icmp_typeICMP_ECHO; //回显请求 icmp-icmp_code0; icmp-icmp_cksum0; icmp-icmp_seq0; icmp-icmp_idpid; tval (struct timeval *)icmp-icmp_data; gettimeofday(tval,NULL); icmp-icmp_cksumcal_chksum((unsigned short *)icmp,sizeof(struct icmp)); //校验 int n; // 发包 n sendto(sockfd, (char *)sendpacket, sizeof(struct icmp), 0, (struct sockaddr *)addr, sizeof(addr)); if (n 1) { printf(ip:%s,sendto error\n,ips); return ERROR; } // 接受 // 由于可能接受到其他Ping的应答消息所以这里要用循环 while(1) { // 设定TimeOut时间这次才是真正起作用的 FD_ZERO(readfds); FD_SET(sockfd, readfds); maxfds sockfd 1; n select(maxfds, readfds, NULL, NULL, timeo); if (n 0) { printf(ip:%s,Time out error\n,ips); close(sockfd); return ERROR; } // 接受 memset(recvpacket, 0, sizeof(recvpacket)); int fromlen sizeof(from); n recvfrom(sockfd, recvpacket, sizeof(recvpacket), 0, (struct sockaddr *)from, (socklen_t *)fromlen); if (n 1) { break; } char *from_ip (char *)inet_ntoa(from.sin_addr); // 判断是否是自己Ping的回复 if (strcmp(from_ip,ips) ! 0) { printf(NowPingip:%s Fromip:%s\nNowPingip is not same to Fromip,so ping wrong!\n,ips,from_ip); return ERROR; } iph (struct ip *)recvpacket; icmp(struct icmp *)(recvpacket (iph-ip_hl2)); printf(ip:%s\n,icmp-icmp_type:%d\n,icmp-icmp_id:%d\n,ips,icmp-icmp_type,icmp-icmp_id); // 判断Ping回复包的状态 if (icmp-icmp_type ICMP_ECHOREPLY icmp-icmp_id pid) //ICMP_ECHOREPLY回显应答 { // 正常就退出循环 break; } else { // 否则继续等 continue; } } int main() { char cPing[16]; printf(Please input ping IP:); scanf(%s,cPing); if(ping(cPing,10000)) { printf(Ping succeed!\n); } else { printf(Ping wrong!\n); } } 测试结果rootan-virtual-machine:~/wyz/test# ./testping Please input ping IP:192.168.1.155 Nowip:192.168.1.155 Fromip:192.168.1.133 Nowip is not same to Fromip,so ping wrong! Ping wrong! rootan-virtual-machine:~/wyz/test# ./testping Please input ping IP:192.168.1.188 ip:192.168.1.188 ,icmp-icmp_type:0 ,icmp-icmp_id:27865 Ping succeed!
相关文章: