当前位置: 首页 > news >正文

常州做网站公司排名网站建设策划报价

常州做网站公司排名,网站建设策划报价,医院网站建设熊掌号,app推广引流渠道2001 年 10 月 01 日大部分人用ping命令只是作为查看另一个系统的网络连接是否正常的一种简单方法。在这篇文章中#xff0c;作者将介绍如何用C语言编写一个模拟ping命令功能的程序。ping命令是用来查看网络上另一个主机系统的网络连接是否正常的一个工具。ping命令的工作原理…2001 年 10 月 01 日大部分人用ping命令只是作为查看另一个系统的网络连接是否正常的一种简单方法。在这篇文章中作者将介绍如何用C语言编写一个模拟ping命令功能的程序。ping命令是用来查看网络上另一个主机系统的网络连接是否正常的一个工具。ping命令的工作原理是向网络上的另一个主机系统发送ICMP报文如果指定系统得到了报文它将把报文一模一样地传回给发送者这有点象潜水艇声纳系统中使用的发声装置。例如在Linux终端上执行ping localhost命令将会看到以下结果:PING localhost.localdomain (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.64 bytes from localhost.localdomain (127.0.0.1): icmp_seq0 ttl255 time112 usec64 bytes from localhost.localdomain (127.0.0.1): icmp_seq1 ttl255 time79 usec64 bytes from localhost.localdomain (127.0.0.1): icmp_seq2 ttl255 time78 usec64 bytes from localhost.localdomain (127.0.0.1): icmp_seq3 ttl255 time82 usec--- localhost.localdomain ping statistics ---4 packets transmitted, 4 packets received, 0% packet lossround-trip min/avg/max/mdev 0.078/0.087/0.112/0.018 ms由上面的执行结果可以看到ping命令执行后显示出被测试系统主机名和相应IP地址、返回给当前主机的ICMP报文顺序号、ttl生存时间和往返时间rtt(单位是毫秒即千分之一秒)。要写一个模拟ping命令这些信息有启示作用。要真正了解ping命令实现原理就要了解ping命令所使用到的TCP/IP协议。ICMP(Internet Control Message,网际控制报文协议)是为网关和目标主机而提供的一种差错控制机制使它们在遇到差错时能把错误报告给报文源发方。ICMP协议是IP层的一个协议但是由于差错报告在发送给报文源发方时可能也要经过若干子网因此牵涉到路由选择等问题所以ICMP报文需通过IP协议来发送。ICMP数据报的数据发送前需要两级封装首先添加ICMP报头形成ICMP报文再添加IP报头形成IP数据报。如下图所示IP报头ICMP报头ICMP数据报由于IP层协议是一种点对点的协议而非端对端的协议它提供无连接的数据报服务没有端口的概念因此很少使用bind()和connect()函数若有使用也只是用于设置IP地址。发送数据使用sendto()函数接收数据使用recvfrom()函数。IP报头格式如下图在Linux中IP报头格式数据结构()定义如下struct ip{#if __BYTE_ORDER __LITTLE_ENDIANunsigned int ip_hl:4; /* header length */unsigned int ip_v:4; /* version */#endif#if __BYTE_ORDER __BIG_ENDIANunsigned int ip_v:4; /* version */unsigned int ip_hl:4; /* header length */#endifu_int8_t ip_tos; /* type of service */u_short ip_len; /* total length */u_short ip_id; /* identification */u_short ip_off; /* fragment offset field */#define IP_RF 0x8000 /* reserved fragment flag */#define IP_DF 0x4000 /* dont fragment flag */#define IP_MF 0x2000 /* more fragments flag */#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */u_int8_t ip_ttl; /* time to live */u_int8_t ip_p; /* protocol */u_short ip_sum; /* checksum */struct in_addr ip_src, ip_dst; /* source and dest address */};其中ping程序只使用以下数据IP报头长度IHL(Internet Header Length)?D?D以字节为一个单位来记录IP报头的长度是上述IP数据结构的ip_hl变量。生存时间TTL(Time To Live)?D?D以秒为单位指出IP数据报能在网络上停留的最长时间其值由发送方设定并在经过路由的每一个节点时减一当该值为时数据报将被丢弃是上述IP数据结构的ip_ttl变量。ICMP报文分为两种一是错误报告报文二是查询报文。每个ICMP报头均包含类型、编码和校验和这三项内容长度为位位和位其余选项则随ICMP的功能不同而不同。Ping命令只使用众多ICMP报文中的两种请求回送‘(ICMP_ECHO)和请求回应‘(ICMP_ECHOREPLY)。在Linux中定义如下#define ICMP_ECHO 0#define ICMP_ECHOREPLY 8这两种ICMP类型报头格式如下在Linux中ICMP数据结构()定义如下struct icmp{u_int8_t icmp_type; /* type of message, see below */u_int8_t icmp_code; /* type sub code */u_int16_t icmp_cksum; /* ones complement checksum of struct */union{u_char ih_pptr; /* ICMP_PARAMPROB */struct in_addr ih_gwaddr; /* gateway address */struct ih_idseq /* echo datagram */{u_int16_t icd_id;u_int16_t icd_seq;} ih_idseq;u_int32_t ih_void;/* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */struct ih_pmtu{u_int16_t ipm_void;u_int16_t ipm_nextmtu;} ih_pmtu;struct ih_rtradv{u_int8_t irt_num_addrs;u_int8_t irt_wpa;u_int16_t irt_lifetime;} ih_rtradv;} icmp_hun;#define icmp_pptr icmp_hun.ih_pptr#define icmp_gwaddr icmp_hun.ih_gwaddr#define icmp_id icmp_hun.ih_idseq.icd_id#define icmp_seq icmp_hun.ih_idseq.icd_seq#define icmp_void icmp_hun.ih_void#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetimeunion{struct{u_int32_t its_otime;u_int32_t its_rtime;u_int32_t its_ttime;} id_ts;struct{struct ip idi_ip;/* options and then 64 bits of data */} id_ip;struct icmp_ra_addr id_radv;u_int32_t id_mask;u_int8_t id_data[1];} icmp_dun;#define icmp_otime icmp_dun.id_ts.its_otime#define icmp_rtime icmp_dun.id_ts.its_rtime#define icmp_ttime icmp_dun.id_ts.its_ttime#define icmp_ip icmp_dun.id_ip.idi_ip#define icmp_radv icmp_dun.id_radv#define icmp_mask icmp_dun.id_mask#define icmp_data icmp_dun.id_data};使用宏定义令表达更简洁,其中ICMP报头为字节,数据报长度最大为64K字节。校验和算法?D?D这一算法称为网际校验和算法把被校验的数据位进行累加然后取反码若数据字节长度为奇数则数据尾部补一个字节的以凑成偶数。此算法适用于IPv4、ICMPv4、IGMPV4、ICMPv6、UDP和TCP校验和更详细的信息请参考RFC1071校验和字段为上述ICMP数据结构的icmp_cksum变量。标识符?D?D用于唯一标识ICMP报文, 为上述ICMP数据结构的icmp_id宏所指的变量。顺序号?D?Dping命令的icmp_seq便由这里读出代表ICMP报文的发送顺序为上述ICMP数据结构的icmp_seq宏所指的变量。Ping命令中需要显示的信息包括icmp_seq和ttl都已有实现的办法但还缺rtt往返时间。为了实现这一功能可利用ICMP数据报携带一个时间戳。使用以下函数生成时间戳#includeint gettimeofday(struct timeval *tp,void *tzp)其中timeval结构如下struct timeval{long tv_sec;long tv_usec;}其中tv_sec为秒数tv_usec微秒数。在发送和接收报文时由gettimeofday分别生成两个timeval结构两者之差即为往返时间,即ICMP报文发送与接收的时间差而timeval结构由ICMP数据报携带,tzp指针表示时区一般都不使用赋NULL值。系统自带的ping命令当它接送完所有ICMP报文后会对所有发送和所有接收的ICMP报文进行统计从而计算ICMP报文丢失的比率。为达此目的定义两个全局变量接收计数器和发送计数器用于记录ICMP报文接受和发送数目。丢失数目发送总数-接收总数丢失比率丢失数目/发送总数。现给出模拟Ping程序功能的代码如下/************************************************************ 作者:梁俊辉 ** 时间:2001年10月 ** 名称myping.c ** 说明:本程序用于演示ping命令的实现原理 ************************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #define PACKET_SIZE 4096#define MAX_WAIT_TIME 5#define MAX_NO_PACKETS 3char sendpacket[PACKET_SIZE];char recvpacket[PACKET_SIZE];int sockfd,datalen56;int nsend0,nreceived0;struct sockaddr_in dest_addr;pid_t pid;struct sockaddr_in from;struct timeval tvrecv;void statistics(int signo);unsigned short cal_chksum(unsigned short *addr,int len);int pack(int pack_no);void send_packet(void);void recv_packet(void);int unpack(char *buf,int len);void tv_sub(struct timeval *out,struct timeval *in);void statistics(int signo){ printf(\n--------------------PING statistics-------------------\n);printf(%d packets transmitted, %d received , %%%d lost\n,nsend,nreceived,(nsend-nreceived)/nsend*100);close(sockfd);exit(1);}/*校验和算法*/unsigned short cal_chksum(unsigned short *addr,int len){ int nleftlen;int sum0;unsigned short *waddr;unsigned short answer0;/*把ICMP报头二进制数据以2字节为单位累加起来*/while(nleft1){ sum*w;nleft-2;}/*若ICMP报头为奇数个字节会剩下最后一字节。把最后一个字节视为一个2字节数据的高字节这个2字节数据的低字节为0继续累加*/if( nleft1){ *(unsigned char *)(answer)*(unsigned char *)w;sumanswer;}sum(sum16)(sum0xffff);sum(sum16);answer~sum;return answer;}/*设置ICMP报头*/int pack(int pack_no){ int i,packsize;struct icmp *icmp;struct timeval *tval;icmp(struct icmp*)sendpacket;icmp-icmp_typeICMP_ECHO;icmp-icmp_code0;icmp-icmp_cksum0;icmp-icmp_seqpack_no;icmp-icmp_idpid;packsize8datalen;tval (struct timeval *)icmp-icmp_data;gettimeofday(tval,NULL); /*记录发送时间*/icmp-icmp_cksumcal_chksum( (unsigned short *)icmp,packsize); /*校验算法*/return packsize;}/*发送三个ICMP报文*/void send_packet(){ int packetsize;while( nsend{ nsend;packetsizepack(nsend); /*设置ICMP报头*/if( sendto(sockfd,sendpacket,packetsize,0,(struct sockaddr *)dest_addr,sizeof(dest_addr) )0 ){ perror(sendto error);continue;}sleep(1); /*每隔一秒发送一个ICMP报文*/}}/*接收所有ICMP报文*/void recv_packet(){ int n,fromlen;extern int errno;signal(SIGALRM,statistics);fromlensizeof(from);while( nreceived{ alarm(MAX_WAIT_TIME);if( (nrecvfrom(sockfd,recvpacket,sizeof(recvpacket),0,(struct sockaddr *)from,fromlen)) 0){ if(errnoEINTR)continue;perror(recvfrom error);continue;}gettimeofday(tvrecv,NULL); /*记录接收时间*/if(unpack(recvpacket,n)-1)continue;nreceived;}}/*剥去ICMP报头*/int unpack(char *buf,int len){ int i,iphdrlen;struct ip *ip;struct icmp *icmp;struct timeval *tvsend;double rtt;ip(struct ip *)buf;iphdrlenip-ip_hl2; /*求ip报头长度,即ip报头的长度标志乘4*/icmp(struct icmp *)(bufiphdrlen); /*越过ip报头,指向ICMP报头*/len-iphdrlen; /*ICMP报头及ICMP数据报的总长度*/if( len8) /*小于ICMP报头长度则不合理*/{ printf(ICMP packets\‘s length is less than 8\n);return -1;}/*确保所接收的是我所发的的ICMP的回应*/if( (icmp-icmp_typeICMP_ECHOREPLY) (icmp-icmp_idpid) ){ tvsend(struct timeval *)icmp-icmp_data;tv_sub(tvrecv,tvsend); /*接收和发送的时间差*/rtttvrecv.tv_sec*1000tvrecv.tv_usec/1000; /*以毫秒为单位计算rtt*//*显示相关信息*/printf(%d byte from %s: icmp_seq%u ttl%d rtt%.3f ms\n,len,inet_ntoa(from.sin_addr),icmp-icmp_seq,ip-ip_ttl,rtt);}else return -1;}main(int argc,char *argv[]){ struct hostent *host;struct protoent *protocol;unsigned long inaddr0l;int waittimeMAX_WAIT_TIME;int size50*1024;if(argc2){ printf(usage:%s hostname/IP address\n,argv[0]);exit(1);}if( (protocolgetprotobyname(icmp) )NULL){ perror(getprotobyname);exit(1);}/*生成使用ICMP的原始套接字,这种套接字只有root才能生成*/if( (sockfdsocket(AF_INET,SOCK_RAW,protocol-p_proto) )0){ perror(socket error);exit(1);}/* 回收root权限,设置当前用户权限*/setuid(getuid());/*扩大套接字接收缓冲区到50K这样做主要为了减小接收缓冲区溢出的的可能性,若无意中ping一个广播地址或多播地址,将会引来大量应答*/setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,size,sizeof(size) );bzero(dest_addr,sizeof(dest_addr));dest_addr.sin_familyAF_INET;/*判断是主机名还是ip地址*/if( inaddrinet_addr(argv[1])INADDR_NONE){ if((hostgethostbyname(argv[1]) )NULL) /*是主机名*/{ perror(gethostbyname error);exit(1);}memcpy( (char *)dest_addr.sin_addr,host-h_addr,host-h_length);}else /*是ip地址*/memcpy( (char *)dest_addr,(char *)inaddr,host-h_length);/*获取main的进程id,用于设置ICMP的标志符*/pidgetpid();printf(PING %s(%s): %d bytes data in ICMP packets.\n,argv[1],inet_ntoa(dest_addr.sin_addr),datalen);send_packet(); /*发送所有ICMP报文*/recv_packet(); /*接收所有ICMP报文*/statistics(SIGALRM); /*进行统计*/return 0;}/*两个timeval结构相减*/void tv_sub(struct timeval *out,struct timeval *in){ if( (out-tv_usec-in-tv_usec)0){ --out-tv_sec;out-tv_usec1000000;}out-tv_sec-in-tv_sec;}/*------------- The End -----------*/只有root用户才能利用socket()函数生成原始套接字要让Linux的一般用户能执行以上程序需进行如下的特别操作用root登陆编译以上程序gcc -o myping myping.c其目的有二一是编译二是让myping属于root用户。再执行chmod us myping目的是把myping程序设成SUID的属性。退出root用一般用户登陆执行./myping www.cn.ibm.com有以下执行结果PING www.cn.ibm.com(202.95.2.148): 56 bytes data in ICMP packets.64 byte from 202.95.2.148: icmp_seq1 ttl242 rtt3029.000 ms64 byte from 202.95.2.148: icmp_seq2 ttl242 rtt2020.000 ms64 byte from 202.95.2.148: icmp_seq3 ttl242 rtt1010.000 ms--------------------PING statistics-------------------3 packets transmitted, 3 received , %0 lost由于myping.c是发送完所有的ICMP报文才去接收因此第一、第二和第三个ICMP报文的往返时间依此是3秒秒秒上述结果中rtt信息正反映这一事实。梁俊辉,对Linux的网络应用和程序设计有浓厚兴趣,并且专注于这一方面研究在IBM developerWorks?D?DLinux专区上发表过《NEWT程序设计指南》一文。
http://www.huolong8.cn/news/56036/

相关文章:

  • 佛山微信网站开发网页设计实训总结三百字
  • wordpress 商城站下载地址跨境网络营销是什么
  • 集美区网站建设哪个网站做美食视频网站
  • 深圳网站建设 卓越创外贸英才网
  • 青岛网站推广优化公司北京 网站建设 招标信息
  • 怎么做网站背景个人做什么类型网站
  • 扒人家网站做网站网站建设冷色调
  • 简洁大方的网站首页7年级微机课做网站的软件
  • 教育信息化建设网站小程序外包多少钱
  • 创建个人网站amp 插件 wordpress
  • 旅游网站400电话彩铃wordpress 修改meta
  • 利用模板建网站静态网站怎么样
  • 两学一做网上答题网站辽宁省建设工程信息网首页
  • 搞一个网站花多少钱个人网站风格
  • 网站排名下降原因四川省住房和城乡建设厅网站首页
  • 郑州手机网站推广公司国内管理咨询公司排行
  • 玉田网站建设dedecms 调用wordpress
  • 高权重网站出售oppo手机商城
  • 如果做vr参观网站数码电子产品网站建设策划书
  • 手机网站建设哪家有新乡市四合一网站建设
  • asp.net网站开发是什么网站建设需求说明书
  • 济南建网站送400电话住房建设局网站
  • 网站用户体验设计冠县住房和城乡建设局网站
  • 宝安网站建设哪家便宜深圳装修公司哪家比较好
  • 各类网站导航网络营销工具的案例
  • 做网站的费用计入哪个科目wordpress页面显示
  • 腾讯云win建设网站北京网络安全公司
  • 佛山市品牌网站建设多少钱中国建设网官方网站企业
  • 一个网站两个空间网上书城网站开发外文参考文献
  • 建立门户网站的步骤网站跳转qq