PDA

Visualizza la versione completa : ottenere l'indirizzo ip internet in c++


IroN@xiD
27-02-2003, 23:54
Qualcuno mi sa spiegare come posso ottenere l'indirizzo ip in internet della mia macchina con c++?

Grazie mille!:)
Ciao!! :ciauz:

IroN@xiD
28-02-2003, 17:25
nessuno lo so oppure ho fatto una domanda stupida?:stordita:

TheGreatWorld
01-03-2003, 00:19
fatti una paronamica sulle funzioni in
netdb.h e netinet/in.h.

Su su, un po di lavoro.

bye

r0x
01-03-2003, 01:51
No, la domanda non e` affatto stupida, anzi! :eek: Anche perche` non e` neanche molto scontata la risposta.

Cmq su Linux/Unix puoi agire elencando tutte le interfacce di rete attive e non. Questo codice e` un modo per farlo, e salta volutamente il loopback (127.0.0.1):



#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netdb.h>

int main( int argc, char* argv[] )
{
struct ifconf ifc;
struct ifreq* ifr_array;
struct sockaddr_in* sin;

char buf[ 8192 ];
int s, i, length;

/* apre un socket ausiliario */

s = socket( PF_INET, SOCK_STREAM, 0 );

ifc.ifc_len = sizeof( buf );
ifc.ifc_buf = buf;

/* preleva le informazioni sulle interfacce di rete */

if( ioctl( s, SIOCGIFCONF, ( char* ) &ifc ) < 0 )
{
perror( "Errore su ifc.\n" );
exit( 1 );
}

/* salva il puntatore all`array di strutture */

ifr_array = ifc.ifc_req;

/* numero totale di strutture restituite */

length = ifc.ifc_len / sizeof( struct ifreq );

for( i = 0; i < length; ++i )
{
struct ifreq* ifr = &ifr_array[ i ];

/* elenca solo la famiglia di indirizzi Internet */

if( ifr->ifr_addr.sa_family != AF_INET )
continue;

/* ottiene informazioni sull`interfaccia corrente */

if( ioctl( s, SIOCGIFFLAGS, ( char* ) ifr ) < 0 )
{
perror( "Errore su ifr.\n" );
exit( 1 );
}

/* ignora l`interfaccia di loopback (127.0.0.1) */

if( ifr->ifr_flags & IFF_LOOPBACK )
continue;

/* forza un cast a sockaddr_in delle informazioni sull`indirizzo dell`interfaccia */

sin = ( struct sockaddr_in* ) &ifr->ifr_addr;

/* stampa il nome dell`interfaccia e il corrispondente indirizzo IP */

printf( "%s: %s\n", ifr->ifr_name, inet_ntoa( sin->sin_addr ) );
}

return 0;
}


Per Windows per fortuna il codice e` quasi identico, perche` in fondo ci si basa sulla stessa procedura anche se ovviamente con chiamate diverse ("ovviamente" perche` tanto non c`e` cosa che la Microsoft non si ostini a fare in modo diverso dal MONDO).

Guardare per credere: http://tangentsoft.net/wskfaq/examples/getifaces.html

Ciao.

IroN@xiD
02-03-2003, 15:42
Grazie mille r0x!! :)

Ciao!!
:ciauz:

P.S. x TheGreatWorld. Non che non ho voglia di perdere tempo per studiarmi la cosa o perch sono un fannullone.. perch a parte la lettura del manuale C ansi e lo studio del corso su c++ qui su html.it non so nient'altro ;) Quindi di netdb e netinet non ne sapevo nemmeno l'esistenza :bh:

bgp
02-03-2003, 17:31
r0x, puoi spiegarmi un attimo a che serve il programma alla pagina che hai segnalato? Non l'ho capito molto bene, l dice in inglese che serve a prendere delle informazioni dal computer come broadcast addresses, il netmasks...cio?
che il broadcast o il netmask?
sorry per l'ignoranza :tongue:

r0x
02-03-2003, 19:17
Ah guarda, posso dirti che in materia sono ignorante anch`io! :p

Cmq la netmask e` una stringa di bits che and-ata con un indirizzo IP restituisce il network al quale esso appartiene. Per esempio:

IP: 127.0.0.1 (hex: 0x100000FF)
Netmask: 0x000000FF

Network = IP & Netmask = 127.*

Siccome la netmask e` rappresentata da bits contigui, si puo` scrivere anche:

127.0.0.1/8

Dove 8 e` il numero di bits della netmask. In questo caso la netmask e` infatti 0x000000FF, perche` ha i primi 8 bits meno significativi settati a 1.

Un indirizzo di broadcasting di un network e` un indirizzo al quale indirizzandovi un pacchetto esso arrivo a tutti gli indirizzi IP del network.

Dovrebbe essere cosi`, ma non ne sono sicuro perche` non sono molto preparato.. :stordita:

Ciao.

Andrea Simonassi
02-03-2003, 21:37
Incuriosito dall' affermazione di r0x "non c`e` cosa che la Microsoft non si ostini a fare in modo diverso dal MONDO", ho provveduto a verificare, ha ragione, Microsoft per non smentirsi ha deciso che lo standard Unix non andava bene, ho scaricato il seguente codice "Microsoft oriented" da un sito di programmazione, visto che l'MSDN si limita a spiegare che per enumerare le interfacce si usa SIO_GET_INTERFACE_LIST ma poi non spiega come cavolo usare questo parametro su WSAIoctl... manco la documentazione completa nell'MSDN (con quel che costa) ...


#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>

using namespace std;

int doit()
{
SOCKET sd = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
if (sd == SOCKET_ERROR) {
cerr << "Failed to get a socket. Error " << WSAGetLastError() <<
endl; return 1;
}

INTERFACE_INFO InterfaceList[20];
unsigned long nBytesReturned;
if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) {
cerr << "Failed calling WSAIoctl: error " << WSAGetLastError() <<
endl;
return 1;
}

int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
cout << "There are " << nNumInterfaces << " interfaces:" << endl;
for (int i = 0; i < nNumInterfaces; ++i) {
cout << endl;

sockaddr_in *pAddress;
pAddress = (sockaddr_in *) & (InterfaceList[i].iiAddress);
cout << " " << inet_ntoa(pAddress->sin_addr);

pAddress = (sockaddr_in *) & (InterfaceList[i].iiBroadcastAddress);
cout << " has bcast " << inet_ntoa(pAddress->sin_addr);

pAddress = (sockaddr_in *) & (InterfaceList[i].iiNetmask);
cout << " and netmask " << inet_ntoa(pAddress->sin_addr) << endl;

cout << " Iface is ";
u_long nFlags = InterfaceList[i].iiFlags;
if (nFlags & IFF_UP) cout << "up";
else cout << "down";
if (nFlags & IFF_POINTTOPOINT) cout << ", is point-to-point";
if (nFlags & IFF_LOOPBACK) cout << ", is a loopback iface";
cout << ", and can do: ";
if (nFlags & IFF_BROADCAST) cout << "bcast ";
if (nFlags & IFF_MULTICAST) cout << "multicast ";
cout << endl;
}

return 0;
}

int main()
{
WSADATA WinsockData;
if (WSAStartup(MAKEWORD(2, 2), &WinsockData) != 0) {
cerr << "Failed to find Winsock 2.2!" << endl;
return 2;
}

int nRetVal = doit();

WSACleanup();

return nRetVal;
}

r0x
02-03-2003, 23:05
E` lo stesso codice del link in fondo al mio post. :D

Andrea Simonassi
03-03-2003, 08:40
eh eh :D tu dici, potevi risparmiarti un sacco di tempo cliccando sul link che ho dato????

Come al solito hai ragione :D

Comunque ci dimostra quanto buone siano le chiavi di ricerca di quel sito sui vari motori di ricerca..... :p

Loading