当前位置:  技术问答>linux和unix

关于icmp网络编程的一个问题

    来源: 互联网  发布时间:2016-05-01

    本文导语:  各位大虾请帮忙,小弟在linux下写了个ping程序,编译能够成功,但是运行就是有问题,有时能通,有时不能通,总是解决不了,源程序以及运行结果帖如下: #include  #include  #include  #include  #include  #include  #include  ...

各位大虾请帮忙,小弟在linux下写了个ping程序,编译能够成功,但是运行就是有问题,有时能通,有时不能通,总是解决不了,源程序以及运行结果帖如下:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//#include 
#include 
#include 
#include 
#include 
#include 


//#define ICMP_HEADSIZE 8
//#define IP_HEADSIZE 20
#define datalen 56

#define MAX(a,b)  ((a)>(b))?(a):(b)
#define MIN(a,b)  ((a)>(b))?(b):(a)

/*typedef struct tagIpHead
{
  u_char   ip_verlen;
  u_char   ip_tos;
  u_char   ip_len;
  u_char   ip_id;
  u_char   ip_flagoff;
  u_char   ip_ttl;
  u_char   ip_proto;
  u_short  ip_chksum;
  u_long   ip_src_addr;
  u_long   ip_dst_addr;
}IPHEAD;

typedef struct tagIcmpHead
{
  u_char icmp_type;
  u_char icmp_code;
  u_short icmp_chksum;
  u_short icmp_id;
  u_short icmp_seq;
  u_char icmp_data[1];
}ICMPHEAD;*/

/*=====================================================
 ======================================================*/
u_short ChkSum(u_short *pIcmpData,int iDataLen)
{
  u_short iSum;
  u_short iOldByte=0;
  unsigned short *w=pIcmpData;
  int len=iDataLen;
  iSum=0;
  
  while(len>1)
    {
      iSum +=*w++;
      len-=2;
    }
  
  if(len==1)
    {
      *(u_char*)(&iOldByte)=*(u_char*)w;
      iSum+=iOldByte;
    }
  iSum=(iSum>>16)+(iSum&0xffff);
  iSum+=(iSum>>16);
  iOldByte=~iSum;
  printf("chsum is %dn",iOldByte);
  return(iOldByte);
}

/*=====================================================
 =====================================================*/
long time_now()
{
  struct timeval now;
  long lPassed;
  gettimeofday(&now,0);
  lPassed=now.tv_sec*1000000 + now.tv_usec;//化为微妙计算
  return lPassed;
}
int time=1;
char * host;
char * prog;
extern errno;
long lSendTime;
u_short seq;
//int iTimeOut;
int sock,sent=0,recvd;
float max,min,total;
u_long lHostIp;
char buf[200];//发送缓冲区
char buf1[200];//接收缓冲区
struct sockaddr_in it;
struct sockaddr_in from;
pid_t pid;
int fromlen=sizeof(from);
int ping();
void stat();
main(int argc,char ** argv)
{
  struct hostent*h;
  //char buf1[200];
  char dst_host[32];
  int i,namelen;
  int flag;
  struct ip* pIpHead;
  struct icmp* pIcmpHead;
  struct protoent *protocol;
  int size1=50*1024;
  pid=getpid();

  if(argcp_proto))h_addr,&it.sin_addr,h->h_length);
      sprintf(dst_host,"%s(%s)",host,inet_ntoa(it.sin_addr));
    }
  else
    {
      fprintf(stderr,"bad IP or hostn");
      exit(3);
    }
  namelen=sizeof(it);
  printf("nDigger pinging %s,send %d bytesn",dst_host,datalen);
  seq=0;
  sigset(SIGINT,&stat);
  for(;;)
    {
      register  int  size;//寄存器变量占用单独的一个寄存器,这样频繁使用该寄存器相对于读取内存来说效率就提高了 , 该类型变量只有int和char变量
      register u_char ttl;
      float  delta;
      register iIpHeadLen;
      int len1;
      
     ping();
     size=recvfrom(sock,buf1,sizeof(buf1),0,(struct sockaddr *)&from,&fromlen);
     if(size==-1 && errno==EINTR)
{
  continue;
}
      delta=(float)((time_now()-lSendTime)/1000.0);
    
      pIpHead=(struct ip*)buf1;
      iIpHeadLen=(int)((pIpHead->ip_hl&0x0f)icmp_id!=pid || pIcmpHead->icmp_seq!=seq)
{
  fprintf(stderr,"i will continue for ICMPHEAD->id/seqn");
  continue;
}
      sprintf(buf1,"icmp_seq=%u bytes=%d ttl=%d",pIcmpHead->icmp_seq,len1,ttl);
      fprintf(stderr,"reply from %s:%s time=%f msn",host,buf1,delta);
      max=MAX(delta,max);
      min=min?MIN(delta,min):delta;
      total+=delta;
      ++recvd;
      ++seq;
      printf("and now seq is %dn",seq);
    }
}

/*======================================================================
  ======================================================================*/
ping()
{
  //char buf[200];
  int iPacketSize;
  struct timeval *tval;
  long data=20;
  
  struct icmp*pIcmpHead1=(struct icmp*)buf;
  pIcmpHead1->icmp_type=ICMP_ECHO;
  pIcmpHead1->icmp_code=0;
  pIcmpHead1->icmp_id=pid;
  pIcmpHead1->icmp_seq=seq;
  pIcmpHead1->icmp_cksum=0;
  fprintf(stderr,"but icmp_seq is %dn",seq);
  *((long*)pIcmpHead1->icmp_data)=data;
  //tval=(struct timeval *)pIcmpHead1->icmp_data;
  //gettimeofday(tval,NULL);
  iPacketSize=datalen+8;
  pIcmpHead1->icmp_cksum=ChkSum((u_short*)pIcmpHead1,iPacketSize);
  lSendTime=time_now();
  if(sendto(sock,buf,iPacketSize,0,(struct sockaddr*)&it,sizeof(it))type
but icmp_seq is 0
chsum is 59363
this time is No.2
reply from letueo:icmp_seq=0 bytes=64 ttl=64 time=1000.153015 ms
and now seq is 1
but icmp_seq is 1
chsum is 59362
this time is No.3
i will continue for ICMPHEAD->type
but icmp_seq is 1
chsum is 59362
this time is No.4
i will continue for ICMPHEAD->id/seq
but icmp_seq is 1
chsum is 59362
this time is No.5
i will continue for ICMPHEAD->type
but icmp_seq is 1
chsum is 59362
this time is No.6
reply from letueo:icmp_seq=1 bytes=64 ttl=64 time=1000.166016 ms
and now seq is 2
but icmp_seq is 2
chsum is 59361
this time is No.7

----letueo ping statistics summerized by Digger----
6 packets sent,2 packets received,66.67%lost
round_trip min/avg/max:1000.153015/1000.159546/1000.166016 ms

|
两个问题, seq收发要加ntohs, 还有, 不要用本机做测试。

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 请教关于ICMP的问题
  • 广播icmp包遇到的问题
  • 请教一下linux 系统下用icmp 发包 的问题
  • 高分求助icmp_hdr()函数的问题
  • ip_icmp.h编译不能通过?
  • 怎么抓取icmp包?
  • 不是很理解的ICMP
  • icmp.c中的HZ常量在哪定义
  • icmp 中能不能使用 epoll
  • 初学iptables,请问ICMP、MASQUERADE是什么?
  • 网关可以通过ICMP报文来控制客户机向外界的udp请求吗?
  • 请教ICMP-重定向报文产生路由的生存期?
  • 请问大侠们,IPPROTO_ICMP的宏定义在哪儿??
  • 使用原始套接字来发送一个icmp包,不适用setsockopt做控制会怎么样?
  • AIX 下如何取得ICMP的收发包率???
  • ICMP时间戳请求与应答
  • icmp dereferencing pointer to incomplete type
  • (菜鸟飞飞)原始套接字ICMP包无法接收(谢谢回答,急着用哈)
  • 修改icmp
  • 启用iptables防火墙,要求INPUT方向允许任意主机访问ICMP、TCP的21、22、80、139、445端口,INPUT其他默认禁止访问。
  • python构造icmp echo请求和实现网络探测器功能代码分享
  • 用raw socket实现一个ICMP_ECHO的功能,出错了!


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3