Linux拓展應用之ping功能實現詳解

2021-08-27 05:57:55 字數 3058 閱讀 1750

#define max_wait_time 5 //接收超時5秒

#define max_no_packets 3

char sendpacket[packet_size];

char recvpacket[packet_size];

int sockfd,datalen=56;

int nsend=0,nreceived=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); //對icmp包進行校驗

int pack(int pack_no); //填充icmp報文

void send_packet(void); //傳送icmp包

void recv_packet(void); //接收icmp包

int unpack(char *buf,int len); //解析收到的icmp包

void tv_sub(struct timeval *out,struct timeval *in); //計算時間差

void statistics(int signo)

/*校驗和演算法*/

unsigned short cal_chksum(unsigned short *addr,int len)

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

這個2位元組資料的低位元組為0,繼續累加*/

if( nleft==1)

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

sum+=(sum>>16);

answer=~sum;

return answer;

} /*設定icmp報頭*/

int pack(int pack_no)

/*傳送1個icmp報文*/

void send_packet()

return;

} /*接收所有icmp報文*/

void recv_packet()

} gettimeofday(&tvrecv,null); /*記錄接收時間*/

if(unpack(recvpacket,n)==-1) /*收到的包不是icmp包,繼續接收*/

else /*收到回應包,結束迴圈*/

}} /*剝去icmp報頭*/

int unpack(char *buf,int len)

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

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

else

}int main(int argc,char *argv)

if( (protocol=getprotobyname("icmp") )==null) //獲得icmp協議的屬性,如果出錯,說明不支援icmp協議

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

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

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

setuid(getuid()); //getuid獲取當前程序的實際使用者,setuid設定當前程序的有效使用者

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

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

setsockopt(sockfd,sol_socket,so_rcvbuf,&size,sizeof(size) ); //修改套接字屬性

bzero(&dest_addr,sizeof(dest_addr));

dest_addr.sin_family=af_inet; //ping採用的是網路協議

/*判斷是主機名還是ip位址*/

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

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

printf("ping %s (%s): %d bytes data in icmp packets.\n",host->h_name,

inet_ntoa(dest_addr.sin_addr),datalen);

} else /*是ip位址*/

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

pid=getpid();

signal(sigint, statistics);//捕獲sigint訊號,交由statistics函式處理

while(1)

return 0;

} /*兩個timeval結構相減*/

Linux拓展應用之重定向程式設計

使用dup 及dup2函式可以實現linux的標準輸入輸出重定向功能。原理很簡單,即關閉標準的輸入輸出裝置 0 1 2 開啟或複製某普通檔案,並使其檔案描述符為0 1 2。dup 及dup2 函式宣告如下 from usr include unistd.h int dup int fd int du...

Linux應用 之 訊號

1.訊號可以理解為軟體中斷,是在軟體層次上對中斷機制的一種模擬,在原理上,乙個程序收到乙個訊號與處理器收到乙個中斷請求可以說是差不多的。2.訊號機制的根本是每個程序都維護著一張訊號表,通過訊號表的操作。訊號是用位圖存的,只有乙個bit。3.訊號的 需要經過核心控制,這是為了安全考慮。3.1.訊號是如...

linux應用之 程序通訊

程序間通訊基礎 程序間通訊的英文縮寫 ipc 為什麼需要程序間通訊?資料傳輸,資源共享,通知事件,程序控制等。linux程序間通訊方式 6種 管道,訊號,訊息佇列,共享記憶體,訊號量,套接字。各種程序間通訊方式詳解 1 管道通訊 int pipe int name 2 1 成功返回0 失敗返回 1 ...