当前位置: 技术问答>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
#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.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。