Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Мини ping

Ответить
Настройки темы
Мини ping
lehha


Сообщения: n/a

Профиль | Цитировать


Всем привет!
Возникла следующая проблемка, необходимо отбросить "мертвые" IP адреса.
При проходе по подсети я коннектюсь к каждому айпишнику, но если в данный момент компьютер не включен то коннект проходит очень долго и изза этого тормозится весь процесс. Вопрос в том как мне реализовать этот мини пинг? Знаю что пинг использует ICMP протокол, но как мне правильно настроить сокет?? Кто с этим работал??
Вот кусочек моего кода проверки наличия компа в сети.
Код: Выделить весь код
	if (WSAStartup(0x0101, &wsadata)!=SOCKET_ERROR)
		{		 
			SOCKET s=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);		
			if (s!=INVALID_SOCKET)
			{
                                    sockaddr_in adrr;	
				int	nTempTTL = 1;	//TTL Какое должно быть 
значение?? в чем оно измеряется в секундах или в мили секундах??
				setsockopt(s, IPPROTO_IP, IP_TTL, (char*) &nTempTTL, sizeof(nTempTTL));
                                    int nTempTOS = 1; //TOS - type-of-service, что это такое счем едет какие значения принимает??
				setsockopt(s, IPPROTO_IP, IP_TOS, (char*) &nTempTOS, sizeof(nTempTTL));
                                    unsigned int ip = inet_addr(FullAddress);
				phe = gethostbyaddr((char*)&ip,4,AF_INET );	
                               	adrr.sin_addr.S_un.S_addr=((struct in_addr *)phe->h_addr_list[0])->s_addr;
                                    char buff[100];
				adrr.sin_family = AF_INET;				
				sendto(s, buff, sizeof(buff), 0, (sockaddr*)&addr, sizeof(addr))
				re = WSAGetLastError();
			}
		}
И так вопросов сразу оч много
TTL Какое должно быть значение?? в чем оно измеряется в секундах или в мили секундах??
TOS - type-of-service, что это такое счем едет какие значения принимает??
На какой порт отсылать информацию, что должен содержать buff.
Спасибо за рание.

Отправлено: 09:25, 30-12-2005

 
lehha


Сообщения: n/a

Профиль | Цитировать


Всем спасибо разобрался, если интересует могу отпостить год.

Отправлено: 08:29, 13-01-2006 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


lehha
Интересно было бы глянуть. Я в своё время отказался от ICMP (линукс потому что нужен был обязательно), сделал на TCP обычном. Ибыл там у меня запар один... В общем, пишите Ещё кому-нибудь пригодится...

Отправлено: 00:44, 14-01-2006 | #3

lehha


Сообщения: n/a

Профиль | Цитировать


Код: Выделить весь код
#pragma once
#include "Ping.h"

inline USHORT checksum(USHORT *buffer, int size) { 
	unsigned long cksum=0; 
	while(size >1) 
	{ 
		cksum+=*buffer++; 
		size -=sizeof(USHORT); 
	} 
	if(size ) 
	{ 
		cksum += *(UCHAR*)buffer; 
	} 
	cksum = (cksum >> 16) + (cksum & 0xffff); 
	cksum += (cksum >>16); 
	return (USHORT)(~cksum); 
} 

inline BOOL decode_resp(char *buf, int bytes,struct sockaddr_in *from)
{
	IpHeader *iphdr; 
	IcmpHeader *icmphdr; 
	unsigned short iphdrlen; 
	iphdr = (IpHeader *)buf; 
	iphdrlen = iphdr->h_len * 4 ;
	if (bytes  < iphdrlen + ICMP_MIN)
		return TRUE;
	icmphdr = (IcmpHeader*)(buf + iphdrlen); 
	if (icmphdr->i_type != ICMP_ECHOREPLY)
		return FALSE; 	
	if (icmphdr->i_id != (USHORT)GetCurrentProcessId())
		return FALSE; 	
	return TRUE;
} 
BOOL Ping(char* host)
{
	WSADATA WSAData; 
	SOCKET sockRaw;
	if (WSAStartup(MAKEWORD(2,1),&WSAData)!= 0) 
		return FALSE;
	 sockRaw = WSASocket (AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,0);
	 if (sockRaw==INVALID_SOCKET)
		 return FALSE;
	int timeout = 1,  bread; 
	bread = setsockopt (sockRaw, IPPROTO_IP , IP_TTL, (char*)&timeout, sizeof(timeout)); 
	if (bread == SOCKET_ERROR) 
	{		
		closesocket(sockRaw);
		WSACleanup( );
		return FALSE; 	
	}	
	timeout = 1; 
	bread = setsockopt(sockRaw, IPPROTO_IP , IP_TTL, (char*)&timeout, sizeof(timeout)); 
	if(bread == SOCKET_ERROR) 
	{		
		closesocket(sockRaw);
		WSACleanup( );
		return FALSE; 	
	}
	SOCKADDR_IN dest_sin, from_sin; 
	memset(&dest_sin,0,sizeof(dest_sin)); 	
	dest_sin.sin_addr.s_addr = inet_addr((char*)host); 
	dest_sin.sin_family = AF_INET; 
	char *icmp_data = new char[MAX_PACKET];
	memset(icmp_data,0,MAX_PACKET); 
	IcmpHeader *icmp_hdr; 
	char *datapart; 
	icmp_hdr = (IcmpHeader*)icmp_data; 
	icmp_hdr->i_type = ICMP_ECHO; 
	icmp_hdr->i_code = 0; 
	icmp_hdr->i_id = (USHORT)GetCurrentProcessId(); 
	icmp_hdr->i_cksum = 0; 	
	datapart = icmp_data + sizeof(IcmpHeader); 
	int datasize; 
	datasize = DEF_PACKET_SIZE; 
	memset(datapart,'E', datasize - sizeof(IcmpHeader)); 	
	char *recvbuf; 
	recvbuf = (char*)malloc(MAX_PACKET); 
	int iRecvLen; 
	iRecvLen = sizeof (from_sin); 
	int bwrote; 
	((IcmpHeader*)icmp_data)->i_cksum = 0; 
	((IcmpHeader*)icmp_data)->timestamp = GetTickCount(); 
	((IcmpHeader*)icmp_data)->i_cksum = checksum((USHORT*)icmp_data, datasize); 
	bwrote = sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest_sin, sizeof(dest_sin)); 
	if (bwrote == SOCKET_ERROR) 		
	{
		delete icmp_data;
		closesocket(sockRaw);
		WSACleanup( );
		return FALSE; 	
	}	
	bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from_sin, &iRecvLen); 
	if (bread == SOCKET_ERROR) 
	{
		delete icmp_data;
		closesocket(sockRaw);
		WSACleanup( );
		return FALSE; 	
	}
	if (decode_resp(recvbuf,bread,&from_sin)==TRUE)
	{
		delete icmp_data;
		closesocket(sockRaw);
		WSACleanup( );
		return TRUE;
	}
	delete icmp_data;
	closesocket(sockRaw);
	WSACleanup( );
	return FALSE;
}
Если Ping переделать в main() то в принципе рабочая программа, возвращаяет TRUE если пинг прошел.

а вот и хидер
Код: Выделить весь код
#pragma once
#include "Winsock2.h"
#include "WS2TCPIP.H"

#pragma comment( lib, "Ws2_32.lib" ) 

#define ICMP_MIN 8                       
#define DEF_PACKET_SIZE 32 
#define MAX_PACKET 1024 
#define ICMP_ECHO 8 
#define ICMP_ECHOREPLY 0 

typedef struct iphdr { 
	unsigned int h_len:4;  
	unsigned int version:4;
	unsigned char tos;       
	unsigned short total_len; 
	unsigned short ident;       
	unsigned short frag_and_flags;
	unsigned char  ttl; 
	unsigned char proto;        
	unsigned short checksum; 
	unsigned int sourceIP; 
	unsigned int destIP; 
} IpHeader; 

typedef struct _ihdr { 
	BYTE i_type; 
	BYTE i_code; 
	USHORT i_cksum; 
	USHORT i_id; 
	ULONG timestamp; 
} IcmpHeader; 
inline USHORT checksum(USHORT *buffer, int size);
inline BOOL decode_resp(char *buf, int bytes,struct sockaddr_in *from);
BOOL Ping(char* host);
Вообще мне было необходимо проверить наличие компьютера в сети т.е. если от него пришел обратный пакет, то он присутствует, при небольшой доработке можно сделать полноценный пинг.

Отправлено: 08:42, 16-01-2006 | #4



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Мини ping

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Мини-Зарплата 3.0 OSZone Software Новости программного обеспечения 0 20-01-2010 16:30
Мини-Автопредприятие 1.12 OSZone Software Новости программного обеспечения 0 14-12-2009 18:30
Мини-Кулинария 2.1 OSZone Software Новости программного обеспечения 0 25-11-2009 00:30
Мини-Сайт 3.2 OSZone Software Новости программного обеспечения 0 08-11-2009 00:30
Мини юбилей BigMac О сайте и форуме 4 24-09-2006 23:41




 
Переход