Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Узнать IP на C++ (https://forum.antichat.xyz/showthread.php?t=133315)

agrofyl2 06.08.2009 16:48

Узнать IP на C++
 
При тестировании моего тр... в общем моей программы, у меня возникла проблема: нужно было определить айпи-адрес клиента.
Определяю я его так:
Код:

//Получиние своего IP
void GetCurrentIP(char *host) {
        WSADATA wsaData;
        WSAStartup(MAKEWORD(2,2), &wsaData);// инициализируем socket'ы используя Ws2_32.dll для процесса
        char HostName[1024]; // создаем буфер для имени хоста   
        if(!gethostname(HostName, 1024)) // получаем имя хоста 
        {
                if(LPHOSTENT lphost = gethostbyname(HostName)) // получаем IP хоста, т.е. нашего компа
                        strcpy(host,inet_ntoa(*((in_addr*)lphost->h_addr_list[0]))); // преобразуем переменную типа LPIN_ADDR в DWORD   
        }   
        WSACleanup();
}

Определять то он определяет, НО! при тесте обнаружилось, что, например, если у клиента АДСЛ, то он выдает 198.168.0.12 а не внешний айпи, как если бы у клиента был диалап.

Можно ли как-нибудь определить внешний адрес методами С++, не прибегая к стороннему серверу(я конечно могу заставить его подконнектится к моему скрипту, опр. айпишник, или, например, спарсить его с 2ip.ru, но это, как мне кажется, изврат).

Или, например, если заставить его приконнектится к опр.(моему) IP, а самому принять этот коннект, то как тогда определить адрес?

__mad 06.08.2009 18:03

Если клиент за натом/роутером, то узнать реальный IP кроме как через внешний сервер - никак.

Да, и нету тут никакого изврата в парсе IP через внешний сервер.

Для того что бы узнать IP того кто к тебе приконектился смотри 2 переменную в функции accept, а точней поле sin_addr.s_addr в структуре addr.

altblitz 06.08.2009 18:11

agrofyl2,
вопрос интересный.

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

по крайней мере, в ОС не видел реального своего АйПи, лишь 192.* (Вай-Фай)

mr.The 06.08.2009 18:45

тс, делаеш запрос на сайт типа _ttp://www.whatismyip.com/ и регуляркой выдираеш реальный ip. можно не регуляркой, тогда через жопу, но напорядок меньше весит. в любом случае - элементарно пишется. либо можно ещё проще - сделать страницу на фрихосте, которая будет говорить ip. тогда вообще просто

agrofyl2 06.08.2009 21:58

Итак, все получилось.
У меня уже была написана команда, по которой клиент коннектится к опр. IP. И я получаю его IP как говорил __mad:

Код:

#include "iostream"
using namespace std;

#include <winsock2.h>
#pragma comment( lib, "ws2_32.lib" )

int port=2121;

int main() {
        cout << "Work" << endl;
        WSADATA wsd;
        if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
                cout << "WSAData initialize error" << endl;
                return 0;
        }
       
        SOCKET sClient, sServer;
    struct sockaddr_in localaddr, clientaddr;
    int iSize;

        sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
 
        if (sServer == SOCKET_ERROR)
    {
                cout << "Soket error" << endl;
        return 0;
    }
    localaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    localaddr.sin_family = AF_INET;
    localaddr.sin_port = htons(port);

    if (bind(sServer, (struct sockaddr *)&localaddr, sizeof(localaddr)) == SOCKET_ERROR)
    {
                cout << "Can't bind" << endl;
        return 1;
    }
   
    cout << "Bind OK" << endl;

    listen(sServer, 4);

    cout << "Listen OK" << endl;
       
        while(1) {
        iSize = sizeof(clientaddr);
        sClient = accept(sServer, (struct sockaddr *)&clientaddr, &iSize);
                if (sClient == INVALID_SOCKET)
        {       
                        cout << "Accept filed" << endl;
            break;
        }
                cout << "Accept OK" << endl;
                cout << "Client IP: " << inet_ntoa(clientaddr.sin_addr) << endl;
                        //return 0;
        }
    closesocket(sServer);
        cout << "End" << endl;
        WSACleanup();
    return 0;
}

Еще не тестил(только локалхост), но думаю работает.
__mad'у спасибо!!! и вообще всем кто ответил


Время: 21:40