資源簡介
LINUX操作系統下的PING命令完整實現,帶有路由追蹤的功能和CTRL+C終止的功能。
代碼片段和文件信息
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define?PACKET_SIZE?4096
#define?MAX_WAIT_TIME?5
char?sendpacket[PACKET_SIZE];
char?recvpacket[PACKET_SIZE];
double?max_time=0min_time=10000sum_time=0;
int?show_pro=1iobyname=0;
struct?timeval?start_timeend_time;
int?sockfddatalen=56;
int?send_count=4send_interval=1nTTL=-1route_count=-1route_TTL=1;
int?nsend=0nreceived=0npack=0;
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);
int?send_packet(void);
int?recv_packet(void);
int?unpack(char*?buf?int?len);
void?tv_sub(struct?timeval?*out?struct?timeval?*in);
void?cal_time(double?rtt);
void?commandhelp();
void?send_recv();
void?statistics(int?signo)
{
printf(“\n-------------------PING?statistics----------------\n“);
printf(“%d?packets?transmitted??%d?received?%.1f%%?lost\n?“
nsendnreceived((float)nsend-(float)nreceived)/(float)nsend*100);
if(?(max_time!=0)?&&?(sum_time!=0)?)
printf(“rtt?min/avg/max?=?%.3f?%.3f?%.3f?\n“
min_timesum_time/nreceivedmax_time);
close(sockfd);
exit(0);
}
/*校驗和算法*/
unsigned?short?cal_chksum(unsigned?short?*addrint?len)
{
int?nleft=len;
int?sum=0;
unsigned?short?*w=addr;
unsigned?short?answer=0;
while(nleft>1)/*把ICMP報頭二進制數據以2字節為單位加起來*/
{
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;
}
/*設置ICMP報頭*/
int?pack(int?pack_no)
{
int?ipacksize;
struct?icmp?*icmp;
struct?timeval?*tval;
icmp=(struct?icmp*)sendpacket;
icmp->icmp_type=ICMP_ECHO;
icmp->icmp_code=0;
icmp->icmp_cksum=0;
icmp->icmp_seq=pack_no;
icmp->icmp_id=pid;
packsize=8+datalen;
tval?=?(struct?timeval?*)icmp->icmp_data;
gettimeofday(tvalNULL);/*記錄發送時間*/
icmp->icmp_cksum=cal_chksum((unsigned?short?*)icmppacksize);/*校驗算法*/
return?packsize;
}
int?send_packet()
{
int?packetsize;
npack++;
packetsize=pack(npack);/*設置ICMP報頭*/
if(?sendto(?sockfd?sendpacket?packetsize?0
(struct?sockaddr?*)&dest_addrsizeof(dest_addr))?<0?)
{
perror(“sendto?error“);
return?-1;
}
return?0;
}
/*接受報文*/
int?recv_packet()
{
int?nfromlen;
extern?int?errno;
signal(SIGALRMstatistics);
signal(SIGINTstatistics);
fromlen=sizeof(from);
alarm(MAX_WAIT_TIME);
if(?(?n=recvfrom(sockfdrecvpacketsizeof(recvpacket)0
(struct?sockaddr*)&from&fromlen))<0?)
{
if(?errno==EINTR?)?
perror(“recvfrom?error“);
return?-1;
}
gettimeofday(&tvrecvNULL);/*記錄接收時間*/
if(unpack(recvpacketn)==0)
return?0;
return?-1;
}
/*剝去ICMP報頭*/
int?unpack(char?*bufint?len)
{
int?iiphdrlen;
struct?ip?*ip;
struct
- 上一篇:單片機最小系統原理圖
- 下一篇:使用mp4v2將H264+AAC合成mp4
評論
共有 條評論