如何編碼實現Windows下的ping功能

2021-05-17 19:14:50 字數 3222 閱讀 5115

一、資料結構

首先根據ip資料報格式(圖下圖)定義ip資料報頭的資料結構

然後根據icmp回送請求與應答報文格式定義icmp的資料結構

然後分別定義請求回送的資料長度

請求回送的資料結構

icmp回送應答的資料結構

二、函式實現

(1)sendechorequest

函式功能是傳送回送請求資料報,首先定義三個靜態變數

static echorequest echoreq;    // 回送請求資料結構

static nid = 1;        // 識別符號

static nseq = 1;    // 序號

然後填寫回送請求資訊

echoreq.icmphdr.type = icmp_echoreq; // 型別

echoreq.icmphdr.code = 0;             // **

echoreq.icmphdr.checksum = 0;         // 校驗和

echoreq.icmphdr.id = nid++;             // 識別符號

echoreq.icmphdr.seq = nseq++;         // 序號

填寫要傳送的資料

for (i = 0; i < req_datasize; i++)

儲存傳送時間

echoreq.dwtime = gettickcount();

資料存入包中並計算校驗和

echoreq.icmphdr.checksum = in_chsum((u_short*)&echoreq, sizeof(echorequest));

傳送回送請求

nret = sendto(s,

(lpstr)&echoreq,

sizeof(echorequest),

0,(lpsockaddr)lpsttoaddr,

sizeof(sockaddr_in));

(2)recvechoreply

函式功能為接收回送應答資料

dword recvechoreply(socket s, lpsockaddr_in lpsafrom, u_char *pttl)

*pttl = echoreply.iphdr.ttl;    // 取得ttl值

return (echoreply.echorequest.dwtime);    // 返回所用時間

}(3)waitforechoreply

函式功能:等待套接子s是否有資料可讀

int waitforechoreply(socket s)

(3)in_chsum

函式功能計算校驗和

u_short in_chsum(u_short *addr, int len)

if (nleft == 1)

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

sum += (sum >> 16);

answer = ~sum;

return (answer);

}(4)main函式的實現

第一步:定義winsock資料結構wsadata並新建版本號1.1

第二步:呼叫wsastartup初始化wsadata

第三步:呼叫ping函式

第四步:呼叫wsacleanup釋放winsock

void main(int argc, char **argv)

// 初始化winsock

nret = wsastartup(wversionrequested, &wsadata);

if (nret)

if (wsadata.wversion != wversionrequested)

// 呼叫ping函式

ping(argv[1]);

//ping("www.sina.com");

// 釋放winsock

wsacleanup();

}(5)ping

函式功能:實現ping功能

定義函式用到的資料

socket rawsocket;    // 原始套接字

lphostent lphost;    // 主機資訊

sockaddr_in sadest;    // 目的位址

sockaddr_in sasrc;    // 源位址

dword dwtimesent;    // 傳送時間

dword dwelapsed;    // 延遲時間

然後建立乙個原始套接字

建立乙個原始套介面,協議為icmp協議

rawsocket = socket(af_inet, sock_raw, ipproto_icmp);

根據使用者輸入的目的位址獲取

lphost = gethostbyname(pstrhost);

設定目標套介面位址

sadest.sin_addr.s_addr = *((u_long far*)(lphost->h_addr));

sadest.sin_family = af_inet;

sadest.sin_port = 0;

輸出ping程式的提示資訊

printf("/npinging %s [%s] with %d bytes of data:/n",

pstrhost,

inet_ntoa(sadest.sin_addr),

req_datasize);

傳送icmp回送請求

sendechorequest(rawsocket, &sadest);

使用select()等待接收回送的資料

waitforechoreply(rawsocket);

接收應答

dwtimesent = recvechoreply(rawsocket, &sasrc, &cttl);

計算傳輸時間,並輸出提示資訊

dwelapsed = gettickcount() - dwtimesent;

答應應答資訊

printf("/nreply from: %s: bytes=%d time=%ldms ttl=%d",

inet_ntoa(sasrc.sin_addr),

req_datasize,

dwelapsed,

cttl);

}// 關閉套接字

nret = closesocket(rawsocket);

附:程式源**

Windows下檢視修改Mysql的編碼

windows下程式設計連線mysql時,易出現中文亂碼情況,以下是解決方案 1 檢視mysql編碼 show variables like char 發現字符集編碼都是latin1,下面就有必要修改。2 修改編碼 第一步,一定要先把mysql的服務停掉,我的電腦 管理 服務 mysql 停止 第二...

python 學習之Windows 下的編碼處理!

問題1 1 non ascii character xe9 in file 問題原因 程式編碼上出現問題 解決方法 在程式頭部加上 coding utf 8 設定 編碼為utf8即刻正常執行 問題2 windows 下print 亂碼 錯誤原因 原始碼檔案的編碼格式為utf 8,但是window的本...

Windows下c 字元編碼 一

在談c 之前,不得不先來說說各種字元編碼。我們知道最早的英文本元採用ascii,因為英文本元很少,因此乙個char就夠用了。但是由於處理其他語言的需求,8位的char顯然不夠用,這就要求更多位數的編碼。在中國,我們的國標是gbk,準確的說經歷了gb2312 gbk gb18030的發展過程 我們常說...