Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/33: Рейтинг темы: голосов - 33, средняя оценка - 4.67
 Аватар для verchy
0 / 0 / 0
Регистрация: 19.02.2009
Сообщений: 19

Ошибка прикомпилирование кода программы ping

19.02.2009, 18:15. Показов 6695. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер! подскажите пожалуйста у меня возникла проблема на Microsoft Visual C++ .NET не могу отлинковать код программы ping размещенной на сайте форума, выдает ошибку error C2440: '=' : cannot convert from 'HANDLE' to 'HINSTANCE' с чем бы это могло быть связано??? заранее благодарен!!!

Добавлено через 3 минуты 40 секунд
а строка имеет такой вид pIcmpHeader->icmp_id = hInstance; // handle as a unique ID.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.02.2009, 18:15
Ответы с готовыми решениями:

Ошибка в работе кода программы, как исправить
#include <iostream> #include <iterator> #include <list> #include <algorithm> int main() { std::list<int> lst = { 1, 2,...

Что-то наподобие программы ping
только начал учится на c++ и вот такой вопрос, никак немогу написать программу чтобы проверять подключение, к примеру ввести IP:порт и...

При загрузке полученой программы для добавления кода возникает ошибка softbttn.ocx could not be loaded
При загрузке полученой проекта для добавления кода возникает ошибка softbttn.ocx could not be loaded crystl32.ocx coul not be loaded--...

12
 Аватар для Otaka
1857 / 714 / 55
Регистрация: 11.12.2008
Сообщений: 1,019
19.02.2009, 18:28
Может можно попробовать сделать приведение типов?
C++
1
pIcmpHeader->icmp_id = (HINSTANCE)hInstance
0
 Аватар для verchy
0 / 0 / 0
Регистрация: 19.02.2009
Сообщений: 19
19.02.2009, 18:35  [ТС]
нет к сожеалению не подходит привидение типов, выдает ещё больше ошибок!

Добавлено через 1 минуту 54 секунды
Otaka, на самом деле я хочу написать небольшую консольку которая будет подавать звуковой сигнал через Бипер в случае пропадения ответа с определённого айпи адреса, вот за основу я и взял исходник программы пинг!
0
 Аватар для Otaka
1857 / 714 / 55
Регистрация: 11.12.2008
Сообщений: 1,019
19.02.2009, 19:40
Как там в Вижл С я не знаю, но я делал Пинг в Билдере 6, без проблем, но там, вроде бы(??), нету заголовочных файлов к icmp, я описания структур скопировал из MSDN:
C++
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
#include<winsock.h>
#include<vcl.h>
#pragma comment(lib,"ws2_32.lib")
#pragma once
class CPinger
{
typedef struct ip_option_information
{
UCHAR Ttl;
UCHAR Tos;
UCHAR Flags;
UCHAR OptionsSize;
PUCHAR OptionsData;
} IP_OPTION_INFORMATION,  *PIP_OPTION_INFORMATION;
typedef struct {
union {
struct {
u_char s_b1,s_b2,s_b3,s_b4;
} S_un_b;
struct {
 u_short s_w1,s_w2;
 } S_un_w;
 u_long S_addr;
 } S_un;
} IPAddr;
 
typedef struct _IPV6_ADDRESS_EX_LH
{
USHORT sin6_port;
ULONG sin6_flowinfo;
USHORT sin6_addr[8];
ULONG sin6_scope_id;
} IPV6_ADDRESS_EX,  *PIPV6_ADDRESS_EX;
 
typedef struct icmpv6_echo_reply_lh
{  IPV6_ADDRESS_EX Address;
ULONG Status;
unsigned int RoundTripTime;
} ICMPV6_ECHO_REPLY,
*PICMPV6_ECHO_REPLY;
typedef struct icmp_echo_reply
{
IPAddr Address;
ULONG Status;
ULONG RoundTripTime;
USHORT DataSize;
USHORT Reserved;
PVOID Data;
struct ip_option_information Options;
}ICMP_ECHO_REPLY,  *PICMP_ECHO_REPLY;
HANDLE (*pIcmpCreateFile)(void);
HANDLE (*pIcmpCloseHandle)(HANDLE h);
DWORD (*pIcmpSendEcho)(
          HANDLE IcmpHandle,
           IPAddr DestinationAddress,
            LPVOID RequestData,
           WORD RequestSize,
          PIP_OPTION_INFORMATION RequestOptions,
        LPVOID ReplyBuffer,
           DWORD ReplySize,
           DWORD Timeout
      );
HANDLE hIcmp;
//Функция, которая получает стороку IP из неизвестно какой переменной
//Использовать только в OpenHost;
String CrStrFrIP(int add)
{
String end;
end+=IntToStr(add & 0xff)+".";
end+=IntToStr((add>>8) & 0xff)+".";
end+=IntToStr((add>>16) & 0xff)+".";
end+=IntToStr((add>>24) & 0xff);
return end;
}
//--------------------
//--------------------
IPAddr addr;
in_addr Address;
UCHAR pBuf[5000];
UCHAR pReplyBuf[5000];
 
public:              //PUBLIC     PUBLIC    PUBLIC      PUBLIC
String hostname;
int iHostIp;
String sHostIp;
 
int    iCurrentHostIP;
String sCurrentHostIP;
int ElapsedTime;
 
int TimeOut;
//--------------------
CPinger()
        {
        WSADATA wsa;
    WSAStartup(MAKEWORD(1, 1), &wsa);
        hIcmp = LoadLibrary("ICMP.DLL");
    if (hIcmp == NULL)
            {
        ShowMessage("Can't load ICMP DLL");
        return;
                }
        pIcmpCreateFile = (HANDLE (*)(void)) GetProcAddress(hIcmp,"IcmpCreateFile");
    pIcmpSendEcho = (DWORD (*)( HANDLE IcmpHandle,IPAddr DestinationAddress,
        LPVOID RequestData,WORD RequestSize,PIP_OPTION_INFORMATION RequestOptions,LPVOID ReplyBuffer,DWORD ReplySize,DWORD Timeout)) GetProcAddress(hIcmp,"IcmpSendEcho");
    pIcmpCloseHandle = (HANDLE (*)(HANDLE h)) GetProcAddress(hIcmp,"IcmpCloseHandle");
    in_addr Address;
    if (pIcmpCreateFile == NULL)
            {
        ShowMessage("ICMP library error");
        return;
            }
        TimeOut=5000;
        }
//--------------------
bool OpenHost(String host)
        {
        hostname=host;
        LPHOSTENT hp = gethostbyname(host.c_str());
    if (hp== NULL)return false;
        memcpy(&addr, hp->h_addr, hp->h_length);
        sHostIp=CrStrFrIP(addr.S_un.S_addr);
        iHostIp=addr.S_un.S_addr;
        return true;
        }
bool Ping(int Steps)//максимальное колличество шагов, за которое должен быть найден сайт.
        {
        iCurrentHostIP=0;
        sCurrentHostIP="";
        int iPacketSize=32;
        HANDLE hIP = pIcmpCreateFile();
        FillMemory(pBuf, iPacketSize, 80);
 
        int iReplySize = sizeof(ICMP_ECHO_REPLY) + iPacketSize;
        ICMP_ECHO_REPLY* pEchoReply = (ICMP_ECHO_REPLY*) pReplyBuf;
 
        IP_OPTION_INFORMATION ipOptionInfo;
        ZeroMemory(&ipOptionInfo, sizeof(IP_OPTION_INFORMATION));
        ipOptionInfo.Ttl = Steps;
        DWORD nRecvPackets = pIcmpSendEcho(hIP,addr, pBuf, iPacketSize,&ipOptionInfo, pReplyBuf, iReplySize, TimeOut);
        if(nRecvPackets != 1)
        {
                return false;
        }
        memcpy(&iCurrentHostIP, (void*)&pEchoReply->Address, 4);
        ElapsedTime = pEchoReply->RoundTripTime;
        sCurrentHostIP=CrStrFrIP(iCurrentHostIP);
//        pIcmpCloseHandle(hIP);
        return true;
        }
~CPinger()
        {
        FreeLibrary(hIcmp);
        hIcmp=NULL;
        }
//--------------------
};
В вижле это не скомпилируется конечно, так как используются некоторые билдеровские функции и классы, но скажи, где это pIcmpHeader, и что бы ему нельзя было приравнять HANDLE.
Ты выложи свою функцию, а там и посмотрим что можно сделать.
1
 Аватар для verchy
0 / 0 / 0
Регистрация: 19.02.2009
Сообщений: 19
19.02.2009, 21:08  [ТС]
C++
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#include <winsock.h>
 
#define HOST_NAME "www.sources.ru" // Любое доменное имя
#define WINSOCK_VERSION 0x0101 // Версия винсока 1.1
#define NO_FLAGS 0 // Флаги не указываем
// В RFC 792 определены значения сообщений ICMP
#define ICMP_ECHO 8 // An ICMP echo message
#define ICMP_ECHOREPLY 0 // An ICMP echo reply message
#define ICMP_HEADERSIZE 8 
 
struct ip // Структура заголовка IP
{
BYTE ip_verlen; // Version and header length
BYTE ip_tos; // Type of service
WORD ip_len; // Total packet length 
UINT ip_id; // Datagram identification 
WORD ip_fragoff; // Fragment offset 
BYTE ip_ttl; // Time to live 
BYTE ip_proto; // Protocol
UINT ip_chksum; // Checksum 
IN_ADDR ip_src_addr; // Source address 
IN_ADDR ip_dst_addr; // Destination address 
BYTE ip_data[1]; // Variable length data area
};
 
struct icmp // Структура заголовка ICMP
{
BYTE icmp_type; // Type of message
BYTE icmp_code; // Type "sub code" (zero for echos)
WORD icmp_cksum; // 1's complement checksum
HINSTANCE icmp_id; // Unique ID (the instance handle)
WORD icmp_seq; // Tracks multiple pings
BYTE icmp_data[1]; // The start of optional data
};
 
char szPingBuffer[100];
 
 
HINSTANCE hInstance;
 
 
WORD InternetChksum(LPWORD lpwIcmpData, WORD wDataLength)
{
long lSum; // Store the summation
WORD wOddByte; // Left over byte from the summation
WORD wAnswer; // The 1's complement checksum
 
lSum = 0L;
 
while (wDataLength > 1)
{
lSum += *lpwIcmpData++;
wDataLength -= 2;
}
 
// Handle the odd byte if necessary and make sure the top half is zero
if (wDataLength == 1)
{
wOddByte = 0;
*((LPBYTE) &wOddByte) = *(LPBYTE)lpwIcmpData; // One byte only
lSum += wOddByte;
}
 
// Add back the carry outs from the 16 bits to the low 16 bits
lSum = (lSum >> 16) + (lSum & 0xffff); // Add high-16 to low-16
lSum += (lSum >> 16); // Add carry
wAnswer = (WORD)~lSum; // 1's complement, then truncate 
// to 16 bits
return(wAnswer);
}
 
 
BOOL DoPingOperation(HANDLE hInstance)
{
// Локальные переменные
int iPacketSize; // размер ICMP-пакета 
int iHostAddrLength; // Длина адреса сетевого компьютера
int iIPHeadLength; // Длина заголовка IP-датаграммы
int iReceivedBytes; // Количество принятых байтов
int iSentBytes; // Количество посланных байтов
int nProtocol; // Номер протокола ICMP
int iSocketError; // Значение кода ошибки
PDWORD pdwTimeStamp; // Счетчик "тиков" при передаче
DWORD dwReturnTime; // Счетчик "тиков" при приеме
DWORD dwRoundTrip; // Счетчик "тиков" среднего времени пробега
// Структуры, описанные в WINSOCK.H
SOCKADDR_IN sockAddrLocal; // Структуры адреса сокета
SOCKADDR_IN sockAddrHost; // 
SOCKET hSocket; // Дескриптор сокета
LPHOSTENT lpHostEntry; // Структура данных с
// информацией о сетевом компьютере
LPPROTOENT lpProtocolEntry; // Структура данных с информацией о протоколе
 
BYTE IcmpSendPacket[1024]; // Буфер для посылаемых данных
BYTE IcmpRecvPacket[4096]; // Буфер для принимаемых данных 
 
struct icmp *pIcmpHeader; // Указатель на структуру ICMP
struct ip *pIpHeader; // Указатель на структуру-заголовок IP
LPSTR lpszHostName; // Указатель на удаленный сервер времени
 
lpszHostName = HOST_NAME;
 
if ((lpHostEntry = gethostbyname(HOST_NAME)) == NULL) {
wsprintf(szPingBuffer, "Could not get %s IP address.", (LPSTR)lpszHostName);
return(FALSE);
}
 
sockAddrLocal.sin_family = AF_INET;
sockAddrLocal.sin_addr = *((LPIN_ADDR) *lpHostEntry->h_addr_list);
 
// В случае простого сокета, мы должны указывать протокол
if ((lpProtocolEntry = getprotobyname("icmp")) == NULL)
nProtocol = IPPROTO_ICMP;
else
nProtocol = lpProtocolEntry->p_proto;
 
// Создаем простой сокет и указываем ICMP в качестве протокола
if ((hSocket = socket(PF_INET, SOCK_RAW, nProtocol)) == INVALID_SOCKET)
{
wsprintf(szPingBuffer, "Could not create a RAW socket.");
return(FALSE);
}
 
pIcmpHeader = (struct icmp *) IcmpSendPacket; // Point at the data area
pIcmpHeader->icmp_type = ICMP_ECHO; // then fill in the data.
pIcmpHeader->icmp_code = 0; // Use the Sockman instance 
pIcmpHeader->icmp_id = hInstance; // handle as a unique ID.
pIcmpHeader->icmp_seq = 0; // It's important to reset
pIcmpHeader->icmp_cksum = 0; // the checksum to zero.
 
//Значение счетчика "тиков" располагается в необязательной области данных
pdwTimeStamp = (PDWORD)&IcmpSendPacket[ICMP_HEADERSIZE];
*pdwTimeStamp = GetTickCount();
iPacketSize = ICMP_HEADERSIZE + sizeof(DWORD);
pIcmpHeader->icmp_cksum = InternetChksum((LPWORD)pIcmpHeader, iPacketSize);
 
if (pIcmpHeader->icmp_cksum !=0 )
{ 
iSentBytes = sendto(hSocket, (LPSTR) IcmpSendPacket, iPacketSize, 
NO_FLAGS, (LPSOCKADDR) &sockAddrLocal, sizeof(sockAddrLocal));
if (iSentBytes == SOCKET_ERROR) {
closesocket(hSocket);
wsprintf(szPingBuffer,
"The sendto() function returned a socket error.");
return(FALSE);
}
 
if (iSentBytes != iPacketSize) {
closesocket(hSocket);
wsprintf(szPingBuffer,
"Wrong number of bytes sent: %d", iSentBytes);
return(FALSE);
}
 
iHostAddrLength = sizeof(sockAddrHost);
 
iReceivedBytes = recvfrom(hSocket, (LPSTR) IcmpRecvPacket, 
sizeof(IcmpRecvPacket), NO_FLAGS, (LPSOCKADDR) &sockAddrHost,
&iHostAddrLength);
}
else {
closesocket(hSocket);
wsprintf(szPingBuffer, "Checksum computation error! Result was zero!");
return(FALSE);
}
 
closesocket(hSocket);
 
if (iReceivedBytes == SOCKET_ERROR) { 
iSocketError = WSAGetLastError();
if (iSocketError == 10004) {
wsprintf(szPingBuffer,
"Ping operation for %s was cancelled.", 
(LPSTR)lpszHostName);
dwRoundTrip = 0;
return(TRUE);
}
else {
wsprintf(szPingBuffer,
"Socket Error from recvfrom(): %d", iSocketError);
return(FALSE);
}
}
 
dwReturnTime = GetTickCount();
dwRoundTrip = dwReturnTime - *pdwTimeStamp;
 
// Указываем на IP-заголовок принятого пакета
pIpHeader = (struct ip *)IcmpRecvPacket;
 
// Извлекаем биты 4-7 и преобразуем количество З2-битных слов в количество байтов
iIPHeadLength = (pIpHeader->ip_verlen >> 4) << 2;
 
// Проверяем длину, чтобы удостовериться, что ICMP-заголовок принят
if (iReceivedBytes < iIPHeadLength + ICMP_HEADERSIZE) {
wsprintf(szPingBuffer, "Received packet was too short.");
return(FALSE);
}
 
// Указываем на ICMP-сообщение, следующее сразу за IP-заголовком
pIcmpHeader = (struct icmp *) (IcmpRecvPacket + iIPHeadLength);
 
// Проверяем, что мы приняли именно "эхо"-ответ
if (pIcmpHeader->icmp_type != ICMP_ECHOREPLY) {
wsprintf(szPingBuffer,
"Received packet was not an echo reply to your ping.");
return(FALSE);
}
 
// Проверяем, принадлежит ли этот пакет нашей программе
if (pIcmpHeader->icmp_id != (HINSTANCE)hInstance) {
wsprintf(szPingBuffer,
"Received packet was not sent by this program.");
return(FALSE);
}
 
// Да, этот пакет был послан нашей программой. Обратите
// внимание на IP-адрес и имя удаленного компьютера,
// пославшего "эхо"-ответ
lstrcpy(lpszHostName, (LPSTR)lpHostEntry->h_name);
wsprintf(szPingBuffer,
"Round-trip travel time to %s [%s] was %d milliseconds.",
(LPSTR)lpszHostName, (LPSTR)inet_ntoa(sockAddrHost.sin_addr), 
dwRoundTrip);
 
return(TRUE); 
}
 
 
void main ()
{
WSADATA wsaData;
 
WSAStartup(WINSOCK_VERSION, &wsaData);
 
DoPingOperation(hInstance);
MessageBox(NULL, szPingBuffer, "www.sources.ru", MB_OK|MB_ICONSTOP);
 
WSACleanup();
}

вот мой полный листинг пинга ну что-то немогу понять почему эта ошибка появляется
0
 Аватар для Otaka
1857 / 714 / 55
Регистрация: 11.12.2008
Сообщений: 1,019
19.02.2009, 22:59
Ааааа...
Понять-то тут не сложно.

Вот эти куски, по большому счету, можно и удалить.
C++
1
2
3
4
5
6
7
8
9
10
11
12
if (pIcmpHeader->icmp_type != ICMP_ECHOREPLY) {
wsprintf(szPingBuffer,
"Received packet was not an echo reply to your ping.");
return(FALSE);
}
 
// Проверяем, принадлежит ли этот пакет нашей программе
if (pIcmpHeader->icmp_id != (HINSTANCE)hInstance) {
wsprintf(szPingBuffer,
"Received packet was not sent by this program.");
return(FALSE);
}
Это работает как надо. HINSTANCE и HANDLE, это ведь одно и тоже - 4 байтовое число, которое рассматривается либо как int либо как void*(может я не совсем правильно выразился).
C++
1
pIcmpHeader->icmp_id = (HINSTANCE)hInstance
А основная ошибка у тебя в том, что ты пытаешься в функцию wprintf передать LPCSTR - C строку, а надо LPWSTR - 2байтовые символы(юникод).
Вот так вот.
Исправляешь, и все заработает. Я проверил. Visual C++ 2008.
0
0 / 0 / 0
Регистрация: 05.05.2009
Сообщений: 3
05.05.2009, 22:10
Otaka, выложи пожалуйста полный исправленный листинг пинга, который выложил verchy. Я когда заменяю LPCSTR на LPWSTR у меня все равно пишет error C2664: 'wsprintfW' : cannot convert parameter 1 from 'char [100]' to 'LPWSTR'.
0
 Аватар для Otaka
1857 / 714 / 55
Регистрация: 11.12.2008
Сообщений: 1,019
05.05.2009, 22:28
Я его удалил у себя удалил(вместе с Вижуалом).
Ладно. Сейчас исправим.
Вот Вижл С++ 6. Консольный проект с поддержкой МФК. Еще надо добавить в проект wsock32.lib
C++
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
// ping.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include "ping.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
 
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
#include <winsock.h>
 
#define HOST_NAME "www.sources.ru" // Любое доменное имя
#define WINSOCK_VERSION 0x0101 // Версия винсока 1.1
#define NO_FLAGS 0 // Флаги не указываем
// В RFC 792 определены значения сообщений ICMP
#define ICMP_ECHO 8 // An ICMP echo message
#define ICMP_ECHOREPLY 0 // An ICMP echo reply message
#define ICMP_HEADERSIZE 8 
 
struct ip // Структура заголовка IP
{
BYTE ip_verlen; // Version and header length
BYTE ip_tos; // Type of service
WORD ip_len; // Total packet length 
UINT ip_id; // Datagram identification 
WORD ip_fragoff; // Fragment offset 
BYTE ip_ttl; // Time to live 
BYTE ip_proto; // Protocol
UINT ip_chksum; // Checksum 
IN_ADDR ip_src_addr; // Source address 
IN_ADDR ip_dst_addr; // Destination address 
BYTE ip_data[1]; // Variable length data area
};
 
struct icmp // Структура заголовка ICMP
{
BYTE icmp_type; // Type of message
BYTE icmp_code; // Type "sub code" (zero for echos)
WORD icmp_cksum; // 1's complement checksum
HINSTANCE icmp_id; // Unique ID (the instance handle)
WORD icmp_seq; // Tracks multiple pings
BYTE icmp_data[1]; // The start of optional data
};
 
char szPingBuffer[100];
 
 
HINSTANCE hInstance;
 
 
WORD InternetChksum(LPWORD lpwIcmpData, WORD wDataLength)
{
long lSum; // Store the summation
WORD wOddByte; // Left over byte from the summation
WORD wAnswer; // The 1's complement checksum
 
lSum = 0L;
 
while (wDataLength > 1)
{
lSum += *lpwIcmpData++;
wDataLength -= 2;
}
 
// Handle the odd byte if necessary and make sure the top half is zero
if (wDataLength == 1)
{
wOddByte = 0;
*((LPBYTE) &wOddByte) = *(LPBYTE)lpwIcmpData; // One byte only
lSum += wOddByte;
}
 
// Add back the carry outs from the 16 bits to the low 16 bits
lSum = (lSum >> 16) + (lSum & 0xffff); // Add high-16 to low-16
lSum += (lSum >> 16); // Add carry
wAnswer = (WORD)~lSum; // 1's complement, then truncate 
// to 16 bits
return(wAnswer);
}
 
 
BOOL DoPingOperation(HANDLE hInstance)
{
// Локальные переменные
int iPacketSize; // размер ICMP-пакета 
int iHostAddrLength; // Длина адреса сетевого компьютера
int iIPHeadLength; // Длина заголовка IP-датаграммы
int iReceivedBytes; // Количество принятых байтов
int iSentBytes; // Количество посланных байтов
int nProtocol; // Номер протокола ICMP
int iSocketError; // Значение кода ошибки
PDWORD pdwTimeStamp; // Счетчик "тиков" при передаче
DWORD dwReturnTime; // Счетчик "тиков" при приеме
DWORD dwRoundTrip; // Счетчик "тиков" среднего времени пробега
// Структуры, описанные в WINSOCK.H
SOCKADDR_IN sockAddrLocal; // Структуры адреса сокета
SOCKADDR_IN sockAddrHost; // 
SOCKET hSocket; // Дескриптор сокета
LPHOSTENT lpHostEntry; // Структура данных с
// информацией о сетевом компьютере
LPPROTOENT lpProtocolEntry; // Структура данных с информацией о протоколе
 
BYTE IcmpSendPacket[1024]; // Буфер для посылаемых данных
BYTE IcmpRecvPacket[4096]; // Буфер для принимаемых данных 
 
struct icmp *pIcmpHeader; // Указатель на структуру ICMP
struct ip *pIpHeader; // Указатель на структуру-заголовок IP
LPSTR lpszHostName; // Указатель на удаленный сервер времени
 
lpszHostName = HOST_NAME;
 
if ((lpHostEntry = gethostbyname(HOST_NAME)) == NULL) {
wsprintf(szPingBuffer, "Could not get %s IP address.", (LPSTR)lpszHostName);
return(FALSE);
}
 
sockAddrLocal.sin_family = AF_INET;
sockAddrLocal.sin_addr = *((LPIN_ADDR) *lpHostEntry->h_addr_list);
 
// В случае простого сокета, мы должны указывать протокол
if ((lpProtocolEntry = getprotobyname("icmp")) == NULL)
nProtocol = IPPROTO_ICMP;
else
nProtocol = lpProtocolEntry->p_proto;
 
// Создаем простой сокет и указываем ICMP в качестве протокола
if ((hSocket = socket(PF_INET, SOCK_RAW, nProtocol)) == INVALID_SOCKET)
{
wsprintf(szPingBuffer, "Could not create a RAW socket.");
return(FALSE);
}
 
pIcmpHeader = (struct icmp *) IcmpSendPacket; // Point at the data area
pIcmpHeader->icmp_type = ICMP_ECHO; // then fill in the data.
pIcmpHeader->icmp_code = 0; // Use the Sockman instance 
pIcmpHeader->icmp_id = (HINSTANCE)hInstance; // handle as a unique ID.
pIcmpHeader->icmp_seq = 0; // It's important to reset
pIcmpHeader->icmp_cksum = 0; // the checksum to zero.
 
//Значение счетчика "тиков" располагается в необязательной области данных
pdwTimeStamp = (PDWORD)&IcmpSendPacket[ICMP_HEADERSIZE];
*pdwTimeStamp = GetTickCount();
iPacketSize = ICMP_HEADERSIZE + sizeof(DWORD);
pIcmpHeader->icmp_cksum = InternetChksum((LPWORD)pIcmpHeader, iPacketSize);
 
if (pIcmpHeader->icmp_cksum !=0 )
{ 
iSentBytes = sendto(hSocket, (LPSTR) IcmpSendPacket, iPacketSize, 
NO_FLAGS, (LPSOCKADDR) &sockAddrLocal, sizeof(sockAddrLocal));
if (iSentBytes == SOCKET_ERROR) {
closesocket(hSocket);
wsprintf(szPingBuffer,
"The sendto() function returned a socket error.");
return(FALSE);
}
 
if (iSentBytes != iPacketSize) {
closesocket(hSocket);
wsprintf(szPingBuffer,
"Wrong number of bytes sent: %d", iSentBytes);
return(FALSE);
}
 
iHostAddrLength = sizeof(sockAddrHost);
 
iReceivedBytes = recvfrom(hSocket, (LPSTR) IcmpRecvPacket, 
sizeof(IcmpRecvPacket), NO_FLAGS, (LPSOCKADDR) &sockAddrHost,
&iHostAddrLength);
}
else {
closesocket(hSocket);
wsprintf(szPingBuffer, "Checksum computation error! Result was zero!");
return(FALSE);
}
 
closesocket(hSocket);
 
if (iReceivedBytes == SOCKET_ERROR) { 
iSocketError = WSAGetLastError();
if (iSocketError == 10004) {
wsprintf(szPingBuffer,
"Ping operation for %s was cancelled.", 
(LPSTR)lpszHostName);
dwRoundTrip = 0;
return(TRUE);
}
else {
wsprintf(szPingBuffer,
"Socket Error from recvfrom(): %d", iSocketError);
return(FALSE);
}
}
 
dwReturnTime = GetTickCount();
dwRoundTrip = dwReturnTime - *pdwTimeStamp;
 
// Указываем на IP-заголовок принятого пакета
pIpHeader = (struct ip *)IcmpRecvPacket;
 
// Извлекаем биты 4-7 и преобразуем количество З2-битных слов в количество байтов
iIPHeadLength = (pIpHeader->ip_verlen >> 4) << 2;
 
// Проверяем длину, чтобы удостовериться, что ICMP-заголовок принят
if (iReceivedBytes < iIPHeadLength + ICMP_HEADERSIZE) {
wsprintf(szPingBuffer, "Received packet was too short.");
return(FALSE);
}
 
// Указываем на ICMP-сообщение, следующее сразу за IP-заголовком
pIcmpHeader = (struct icmp *) (IcmpRecvPacket + iIPHeadLength);
 
 
lstrcpy(lpszHostName, (LPSTR)lpHostEntry->h_name);
wsprintf(szPingBuffer,
"Round-trip travel time to %s [%s] was %d milliseconds.",
(LPSTR)lpszHostName, (LPSTR)inet_ntoa(sockAddrHost.sin_addr), 
dwRoundTrip);
 
return(TRUE); 
}
 
 
 
 
CWinApp theApp;
 
using namespace std;
 
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;
 
    // initialize MFC and print and error on failure
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
        // TODO: change error code to suit your needs
        cerr << _T("Fatal Error: MFC initialization failed") << endl;
        nRetCode = 1;
    }
    else
    {
    WSADATA wsaData;
 
WSAStartup(WINSOCK_VERSION, &wsaData);
 
DoPingOperation(hInstance);
MessageBox(NULL, szPingBuffer, "www.sources.ru", MB_OK|MB_ICONSTOP);
 
WSACleanup();
    }
 
    return nRetCode;
}
0
0 / 0 / 0
Регистрация: 05.05.2009
Сообщений: 3
05.05.2009, 22:57
Прописал #pragma comment(lib, "ws2_32.lib") - добавил wsock32.lib, но при компеляции выскакивает следующее: Cannot open include file: 'ping.h': No such file or directory. Насколько я понимаю файл должен создаться автоматически в папке с проектом. Но нет. У меня Visual 2005 если это интересно. И код отличается от предыдущего. Честно говоря я профан. Мне нужен листинг который я бы вставил в файл.cpp нажал F7 и посмотрел как программа работает. Именно в C++. В командную строку винды уже вбивал.
0
125 / 123 / 0
Регистрация: 30.03.2009
Сообщений: 766
06.05.2009, 01:16
вот любите вы попрограммировать, а между тем эта задачка решается совсем без него.. всего лишь средствами коммандной строки:
Code
1
2
3
4
5
6
7
8
9
@echo off
 
:loop
for /F %%i in ('ping -n 1 <ip адрес>') do (if %%i==ЏаҐўлиҐ* goto bed)
goto loop
 
 
:bed
echo Fail
чтоб был звучок на стандартный системный динамик, надо вместо FAIL написать ASCII-символ с кодом 0х07
0
0 / 0 / 0
Регистрация: 05.05.2009
Сообщений: 3
06.05.2009, 09:45
Дело в том что мне не нужен звуковой сигнал, мне нужна данная программа работающая на Visual 2005
0
 Аватар для Otaka
1857 / 714 / 55
Регистрация: 11.12.2008
Сообщений: 1,019
06.05.2009, 11:39
Создай в вижл с проект Win32 Console application. назови его ping. в опциях настройки создания проекта включи поддержку MFC(хотя она там и не нужна). а потом в cpp файл вставляй код.
Если уж и это не выйдет, то возьми готовый проект. Правда на VС++ 6(другого сейчас нету), но должно работать.
Вложения
Тип файла: rar ping.rar (11.8 Кб, 92 просмотров)
0
 Аватар для Otaka
1857 / 714 / 55
Регистрация: 11.12.2008
Сообщений: 1,019
06.05.2009, 11:40
verchy посмотри топики 1 и 2 из этой темы.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.05.2009, 11:40
Помогаю со студенческими работами здесь

Есть ping по IP, нет ping по имени
Здравствуйте. Имею AD, DNS, DHCP, терминальная ферма, тонкие клиенты (всё введено в домен) Контроллер домена - ad.mydomen.local...

Ошибка при проверке доступности текстового адреса (NetworkInformation.Ping)
Написал функцию проверки доступности сервера. Если server_address числовой - работает, если текстовый то нет. В чем ошибка? ...

В чем ошибка? При запуске программы открывается консоль и сразу ошибка о завершении программы
К тому же выдает warning: deprecated conversion from string constant to 'char*' . #include &lt;iostream&gt; #include &lt;string.h&gt; #include...

Автоматическая генерация кода программы на основе программы на другом языке программирования
Где может приминяться?Зачем она нужна? И как её примерно делать, не имею представления, спасибо

На основе кода примера программы составить по картинке листинг программы
Program Tochka; {Определение местоположения точки на плоскости. Входные данные:x,y - координаты точки Выходные данные: s - сообщение}...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru