linux下ping C語言實現

2021-08-18 14:09:37 字數 4425 閱讀 3209

1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include in.h>

8 #include 9 #include 10 #include 11 #include 12 #include 13

#define packet_size 4096

14#define max_wait_time 5

15#define max_no_packets 3

16char

sendpacket[packet_size];

17char

recvpacket[packet_size];

18int sockfd,datalen=56;19

int nsend=0,nreceived=0;20

struct

sockaddr_in dest_addr;

21pid_t pid;

22struct sockaddr_in from;23

struct

timeval tvrecv;

24void statistics(int

signo);

25 unsigned short cal_chksum(unsigned short *addr,int

len);

26int pack(int

pack_no);

27void send_packet(void

);28

void recv_packet(void

);29

int unpack(char *buf,int

len);

30void tv_sub(struct timeval *out,struct timeval *in

);31

void statistics(int

signo)

32 38

/*校驗和演算法

*/39 unsigned short cal_chksum(unsigned short *addr,int

len)

40 50

/*若icmp報頭為奇數個位元組,會剩下最後一位元組。把最後乙個位元組視為乙個2位元組資料的高位元組,這個2位元組資料的低位元組為0,繼續累加

*/51

if( nleft==1

)52

55 sum=(sum>>16)+(sum&0xffff

);56 sum+=(sum>>16

);57 answer=~sum;

58return

answer;59}

60/*

設定icmp報頭

*/61

int pack(int

pack_no)

62 77

/*傳送三個icmp報文

*/78

void

send_packet()

79 88 sleep(1); /*

每隔一秒傳送乙個icmp報文

*/89}90

}91/*接收所有icmp報文

*/92

void

recv_packet()

93 105 gettimeofday(&tvrecv,null); /*

記錄接收時間

*/106

if(unpack(recvpacket,n)==-1)continue

;107 nreceived++;

108}

109}

110/*

剝去icmp報頭

*/111

int unpack(char *buf,int

len)

112

125/*

確保所接收的是我所發的的icmp的回應

*/126

if( (icmp->icmp_type==icmp_echoreply) && (icmp->icmp_id==pid) )

127

138else

return -1

;139

}140 main(int argc,char *argv)

141

150if( (protocol=getprotobyname("

icmp

") )==null)

151

154/*

生成使用icmp的原始套接字,這種套接字只有root才能生成

*/155

if( (sockfd=socket(af_inet,sock_raw,protocol->p_proto) )<0

)156

159/*

**root許可權,設定當前使用者許可權

*/160

setuid(getuid());

161/*

擴大套接字接收緩衝區到50k這樣做主要為了減小接收緩衝區溢位的

162的可能性,若無意中ping乙個廣播位址或多播位址,將會引來大量應答

*/163 setsockopt(sockfd,sol_socket,so_rcvbuf,&size,sizeof

(size) );

164 bzero(&dest_addr,sizeof

(dest_addr));

165 dest_addr.sin_family=af_inet;

166/*

判斷是主機名還是ip位址

*/167

if( inaddr=inet_addr(argv[1])==inaddr_none)

168

172 memcpy( (char *)&dest_addr.sin_addr,host->h_addr,host->h_length);

173}

174else

/*是ip位址

*/175 memcpy( (char *)&dest_addr,(char *)&inaddr,host->h_length);

176/*

獲取main的程序id,用於設定icmp的標誌符

*/177 pid=getpid();

178 printf("

ping %s(%s): %d bytes data in icmp packets.\n

",argv[1

],179

inet_ntoa(dest_addr.sin_addr),datalen);

180 send_packet(); /*

傳送所有icmp報文

*/181 recv_packet(); /*

接收所有icmp報文

*/182 statistics(sigalrm); /*

進行統計

*/183

return0;

184}

185/*

兩個timeval結構相減

*/186

void tv_sub(struct timeval *out,struct timeval *in

)187

191out->tv_sec-=in->tv_sec;

192}

193/*

------------- the end -----------

*/

程式編譯:

程式執行結果:

Linux下C語言實現CopyFile

linux下c語言實現檔案拷貝 function copy file from file1 to file2 how to execute copyfile file1 file2 under linux data 2007 05 09 include fprintf stderr,bufsiz i...

Linux下C語言實現UDP Socket程式設計

該博文參考了linux c socket 程式設計之udp一文,在這裡表示感謝!傳送方 file udp sender.c author henry created on 2019年5月29日17 08 13 主要實現 傳送20個文字訊息,然後再傳送乙個終止訊息 include include in...

Linux下C語言實現簡單Shell

include include include include include include include include define max string 256 define signin define signout define signpine const char expst ex...