1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 |
//ping.h #ifndef _CPING_H_ #define _CPING_H_ #include <Winsock2.h> #include <Windows.h> #pragma pack(1) #define ICMP_ECHOREPLY 0 #define ICMP_ECHOREQ 8 #define REQ_DATASIZE 32 // Echo 请求数据的大小 class
CPing { public : //ping host, nRetries-ping次数 bool
Ping( LPCSTR
pstrHost, UINT
nRetries = 4); void
Result( int * nElapseTime, float * fMissPack = NULL, u_char* cTTL = NULL); //void Result(CPing::REQ_RESULT& result); private : int
WaitForEchoReply(SOCKET s); //ICMP回应的请求和回答函数 int
SendEchoRequest(SOCKET, LPSOCKADDR_IN); DWORD
RecvEchoReply(SOCKET, LPSOCKADDR_IN, u_char *); u_short in_cksum(u_short *addr, int
len); private : struct
REQ_RESULT { int
nElapseTime; //请求响应时间。 u_char cTTL; //请求TTL(生存时间) float
fMissPack; //丢包率 }; REQ_RESULT m_Result; }; // IP Header -- RFC 791 typedef
struct tagIPHDR { u_char VIHL; // Version and IHL u_char TOS; // Type Of Service short
TotLen; // Total Length short
ID; // Identification short
FlagOff; // Flags and Fragment Offset u_char TTL; // Time To Live u_char Protocol; // Protocol u_short Checksum; // Checksum struct
in_addr iaSrc; // Internet Address - Source struct
in_addr iaDst; // Internet Address - Destination }IPHDR, *PIPHDR; // ICMP Header - RFC 792 typedef
struct tagICMPHDR { u_char Type; // Type u_char Code; // Code u_short Checksum; // Checksum u_short ID; // Identification u_short Seq; // Sequence char
Data; // Data }ICMPHDR, *PICMPHDR; // ICMP Echo Request typedef
struct tagECHOREQUEST { ICMPHDR icmpHdr; DWORD
dwTime; char
cData[REQ_DATASIZE]; }ECHOREQUEST, *PECHOREQUEST; // ICMP Echo Reply typedef
struct tagECHOREPLY { IPHDR ipHdr; ECHOREQUEST echoRequest; char
cFiller[256]; }ECHOREPLY, *PECHOREPLY; #pragma pack() #endif |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 |
//ping.cpp #include "ping.h" #pragma comment(lib, "ws2_32.lib") bool
CPing::Ping( LPCSTR
pstrHost, UINT
nRetries) { //创建一个Raw套节字 SOCKET rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if
(rawSocket == INVALID_SOCKET) { int
err = WSAGetLastError(); return
false ; } int
nNetTimeout = 1000; //1秒 //发送时限 setsockopt(rawSocket, SOL_SOCKET, SO_SNDTIMEO, ( char
*)&nNetTimeout, sizeof ( int )); //接收时限 setsockopt(rawSocket, SOL_SOCKET, SO_RCVTIMEO, ( char
*)&nNetTimeout, sizeof ( int )); //获得主机信息 LPHOSTENT lpHost = gethostbyname(pstrHost); if
(lpHost == NULL) { return
false ; } //构造目标套节字地址信息 struct
sockaddr_in saDest; struct
sockaddr_in saSrc; saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr)); saDest.sin_family = AF_INET; saDest.sin_port = 3077; //0; DWORD
dwTimeSent; u_char cTTL; int
nRet; int
nRecvNum = 0; int
nTotalTime = 0; //多次ping for
( UINT nLoop = 0; nLoop < nRetries; ++nLoop) { //发送ICMP回应请求 if
((nRet = SendEchoRequest(rawSocket, &saDest)) < 0) { break ; } if
((nRet = WaitForEchoReply(rawSocket)) == SOCKET_ERROR) { break ; } if
(nRet) { //获得回应 if
( (dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL)) < 0) { nRet = dwTimeSent; break ; } //计算时间 nTotalTime += GetTickCount() - dwTimeSent; //Sleep(1000); ++nRecvNum; } } closesocket(rawSocket); if
(nRecvNum > 0 && nRet >= 0) { m_Result.nElapseTime = nTotalTime/nRetries; m_Result.cTTL = cTTL; m_Result.fMissPack = ( float )(nRetries - nRecvNum)/nRetries; return
true ; } return
false ; } //发送ICMPECHO数据包请求 int
CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr) { static
ECHOREQUEST echoReq; static
int nId = 1; static
int nSeq = 1; int
nRet; //构造回应请求 echoReq.icmpHdr.Type = ICMP_ECHOREQ; echoReq.icmpHdr.Code = 0; echoReq.icmpHdr.Checksum = 0; echoReq.icmpHdr.ID = nId++; echoReq.icmpHdr.Seq = nSeq++; for
(nRet = 0; nRet < REQ_DATASIZE; nRet++) echoReq.cData[nRet] = ‘ ‘ +nRet; //保存发送时间 echoReq.dwTime = GetTickCount(); echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof (ECHOREQUEST)); //发送请求 nRet = sendto(s, ( LPSTR )&echoReq, sizeof (ECHOREQUEST), 0, (LPSOCKADDR)lpstToAddr, sizeof (SOCKADDR_IN)); //检查返回值 if
(nRet == SOCKET_ERROR) { } return
(nRet); } //接收ICMPECHO数据包回应 DWORD
CPing::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL) { ECHOREPLY echoReply; int
nRet; int
nAddrLen = sizeof ( struct
sockaddr_in); //接收请求回应 nRet = recvfrom(s, ( LPSTR )&echoReply, sizeof (ECHOREPLY), 0, (LPSOCKADDR)lpsaFrom, &nAddrLen); //检查返回值 if
(nRet == SOCKET_ERROR) { return
nRet; } //返回发送的时间 *pTTL = echoReply.ipHdr.TTL; return (echoReply.echoRequest.dwTime); } //等待回应 int
CPing::WaitForEchoReply(SOCKET s) { struct
timeval Timeout; fd_set readfds; readfds.fd_count = 1; readfds.fd_array[0] = s; Timeout.tv_sec = 1; Timeout.tv_usec = 0; return (select(1, &readfds, NULL, NULL, &Timeout)); } //转换地址 u_short CPing::in_cksum(u_short *addr, int
len) { register
int nleft = len; register
u_short *w = addr; register
u_short answer; register
int sum = 0; while ( nleft > 1 ) { sum += *w++; nleft -= 2; } if ( nleft == 1 ) { u_short u = 0; *(u_char *)(&u) = *(u_char *)w ; sum += u; } sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return
(answer); } void
CPing::Result( int * nElapseTime, float * fMissPack, u_char* cTTL) { if
(nElapseTime) { *nElapseTime = m_Result.nElapseTime; } if
(fMissPack) { *fMissPack = m_Result.fMissPack; } if
(cTTL) { *cTTL = m_Result.cTTL; } } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 |
//main.cpp #include <stdlib.h> #include <iostream> #include <string> #include "ping.h" int main( int
argn, char
*argv[]) { WORD
wVersionRequested; WSADATA wsaData; int
err; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); CPing ping; bool
bResult = false ; if
(argn == 2) { bResult = ping.Ping(argv[1]); } else { bResult = ping.Ping( "www.baidu.com" ); } std::cout << "result : "
<< bResult << std::endl; if
(bResult) { int
nTime; u_char nTTL; float
fMiss; ping.Result(&nTime, &fMiss, &nTTL); std::cout << "time : "
<< nTime << " TTL : "
<< ( int )nTTL << " miss : "
<< fMiss*100 << "% "
<< std::endl; } return
0; } |
原文地址:http://www.cnblogs.com/chunxi/p/3754963.html