Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> CodeBlocks + Сокеты. Непонятное падение. 
V
    Опции темы
CynicRus
Дата 24.9.2012, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 31.5.2012

Репутация: нет
Всего: 5



Доброго времени суток господа, пишу простенький чекер логинов через веб сайт. Получаю информацию следующим способом:
Код

char* OpenURL(char *url) {
    WSADATA lpWSAData;
    SOCKET s;

    // Проверим на правильность введенный адрес.
    // Он должен начинаться с "http://"
    if (memcmp(url,"HTTP://",7)!=0 && memcmp(url,"http://",7)!=0) return(NULL);
    url+=7;

    // Инициализация библиотеки Ws2_32.dll.
    if (WSAStartup(MAKEWORD(1,1),&lpWSAData)!=0) return(NULL);


    // Получим имя хоста, номер порта и путь ----------------------------

    char *http_host=strdup(url); // Имя хоста (HTTP_HOST)
    int port_num=80;             // Номер порта по умолчанию (HTTP_PORT)
    char *http_path=NULL;        // Путь (REQUEST_URI)

    char *pch=strchr(http_host,':');
    if (!pch) {
        pch=strchr(http_host,'/');
        if (pch) {
            *pch=0;
            http_path=strdup(pch+1);
            }
        else http_path=strdup("");
        }
    else {
        *pch=0;pch++;
        char *pch1 = strchr(pch,'/');
        if (pch1) {
            *pch1=0;
            http_path=strdup(pch1+1);
            }
        else http_path=strdup("");

        port_num = atoi(pch);

        if (port_num==0) port_num = 80;
        }

    // Поучаем IP адрес по имени хоста
    struct hostent* hp;
    if (!(hp=gethostbyname(http_host))) {
        free(http_host);
        free(http_path);
        return(NULL);
        }

    // Открываем сокет
    s=socket(AF_INET, SOCK_STREAM, 0);
    if (s==INVALID_SOCKET) {
        free(http_host);
        free(http_path);
        return(NULL);
        }
    struct sockaddr_in ssin;
    memset ((char *)&ssin, 0, sizeof(ssin));
    ssin.sin_family = AF_INET;
    ssin.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr[0];
    ssin.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr[1];
    ssin.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr[2];
    ssin.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr[3];
    ssin.sin_port = htons(port_num);
    printf("Conecting to %d.%d.%d.%d...",(unsigned char)hp->h_addr[0],
                                         (unsigned char)hp->h_addr[1],
                                         (unsigned char)hp->h_addr[2],
                                         (unsigned char)hp->h_addr[3]);
    if (connect(s, (sockaddr *)&ssin, sizeof(ssin))==-1) {
        free(http_host);
        free(http_path);
        printf("Error\n");
        return(NULL);
        }
    printf("Ok\n");
    char *query=(char*)malloc(2048);

    strcpy(query,"GET /");
    strcat(query,http_path);
    strcat(query," HTTP/1.0\nHost: ");
    strcat(query,http_host);
    strcat(query,"\nUser-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
    strcat(query,"\nAccept: */*\n\n");
    printf("%s",query);
    int cnt=send(s,query,strlen(query),0);
    free(http_host);
    free(http_path);
    free(query);
     if (cnt==SOCKET_ERROR) return(NULL);

    cnt=1;
    int size=1024*1024; // 1Mb
    char *result=(char*)malloc(size);
    strcpy(result,"");
    char *result_ptr=result;

    while (cnt!=0 && size>0) {
        cnt=recv (s, result_ptr, sizeof(size),0);
        if (cnt>0) {
            result_ptr+=cnt;
            size-=cnt;
            }
        }
    *result_ptr=0;
    WSACleanup();

    return(result);
    }

Проверяю же текущее имя так:
Код

int checkName(std::string name)
{

    string addr = "http://rscript.org/lookup.php?type=namecheck&name=";
    strcat((char*)addr.c_str(),name.c_str());
    std::string unv = "NOTAVALIBLE";
    std::string str;
    char* answer = OpenURL((char*)addr.c_str());
   // Sleep(10000);
    strcat((char*)str.c_str(),answer);
    if ( str.find(unv) != std::string::npos )
    {
 
        bad++;
        return 1;
    }
    else
    {
        good++;
        return 0;
    }
}

 Так вот. Как только функция checkName возвращает значение, я получаю следующее:
Код

#0 77A05655    ntdll!RtlpSetUserPreferredUILanguages() (C:\Windows\system32\ntdll.dll:??)
#1 779EDA65    ntdll!RtlInitUnicodeString() (C:\Windows\system32\ntdll.dll:??)
#2 779D1A47    ntdll!KiRaiseUserExceptionDispatcher() (C:\Windows\system32\ntdll.dll:??)
#3 77A066AE    ntdll!RtlpSetUserPreferredUILanguages() (C:\Windows\system32\ntdll.dll:??)
#4 779CA0EE    ntdll!KiRaiseUserExceptionDispatcher() (C:\Windows\system32\ntdll.dll:??)
#5 77996536    wtoi64() (C:\Windows\system32\ntdll.dll:??)
#6 77AC98CD    msvcrt!free() (C:\Windows\system32\msvcrt.dll:??)
#7 00000000    0x00650000 in ??() (??:??)
#8 00000000    0x00000000 in ??() (??:??)

 В качестве компилятора использую gcc, система win 7 x32. В чем может быть проблема? При пошаговой отладке вылетает как раз на return в функции checkName.
PM MAIL   Вверх
feodorv
Дата 25.9.2012, 03:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 10
Всего: 45



Цитата(CynicRus @  24.9.2012,  16:44 Найти цитируемый пост)
   string addr = "http://rscript.org/lookup.php?type=namecheck&name=";
    strcat((char*)addr.c_str(),name.c_str());
...
    strcat((char*)str.c_str(),answer);

Что означает сей код? Вы в курсе, что:
Цитата

The returned array points to an internal location with the required storage space for this sequence of characters plus its terminating null-character, but the values in this array should not be modified in the program and are only guaranteed to remain unchanged until the next call to a non-constant member function of the string object.

std::string::c_str.
Таким вольным обращением со строками Вы вполне можете запортить что-нибудь в стеке и получить вылет при return. Да и const просто так разработчики приписали:
Цитата
 
const char* c_str ( ) const;


ЗЫ Намёк:
Цитата

operator+=
    Append to string (public member function)


ЗЗЫ Это верно?
Код

int checkName(std::string name)

Может, как-нибудь
Код

int checkName(std::string &name)
{
  ...
}


Это сообщение отредактировал(а) feodorv - 25.9.2012, 03:28


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
CynicRus
Дата 25.9.2012, 08:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 248
Регистрация: 31.5.2012

Репутация: нет
Всего: 5



Большое спасибо!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.3587 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.