Падение программы C++

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by fire64, 8 Jun 2009.

  1. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    Помогите понять, почему данная программа падает на многих компьютерах


    PHP:
    #include<stdio.h>
    #include<string.h>
    #include<winsock2.h>
    #include<windows.h>

    #define HTTP_PORT        80
    #define HTTP_IP            "63.228.223.110"
    #define HOST            "store.steampowered.com"


    struct mstudiodata_t
    {


        
    int                a[1];
        
    char            b[3];
        
    char            c[3];
    };


    //
    // The Scan function
    //
    int main()
    {
        
    // This function does the actual scanning

        
    WSADATA wsaData;

        
    WSAStartup(MAKEWORD(2,2), &wsaData);


        
    FILE *fp = fopen( "steamid.txt", "wb" );


        for( 
    int index = 0; index < 50000; ++index )
        {

        
        
    SOCKET hSocket; 

        
    // Initialize the socket
        
    hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

        if (
    hSocket == INVALID_SOCKET)
        {
            
    // Return FALSE in case of an error
            
    return FALSE;
        }

        
    sockaddr_in sin;
        
    sin.sin_addr.S_un.S_addr = inet_addr ( HTTP_IP );;
        
    sin.sin_family = AF_INET;
        
        
    sin.sin_port = htons(HTTP_PORT);

        
    fd_set fd_read, fd_write, fd_error;
        
    timeval timeout;
        
    timeout.tv_sec = 3;        // TODO: Hardcoded, should be configurable
        
    timeout.tv_usec = 0;
        
    u_long nNonBlocking = 1;    

        
    // Set socket to non-blocking mode
        
    ioctlsocket(hSocket, FIONBIO, &nNonBlocking);

        
    BOOL bConnected = FALSE;

        
    // Estabilish a TCP connection
        
    connect(hSocket, (sockaddr*)&sin, sizeof(sin));

        
    fd_write.fd_array[0] = hSocket; fd_write.fd_count = 1;
        
    fd_error.fd_array[0] = hSocket; fd_error.fd_count = 1;
        if (
    select(0, 0, &fd_write, &fd_error, &timeout) > 0) 
        {
            if (
    fd_write.fd_count > 0)
            {

                
    // Connection successful
                
    bConnected = TRUE;
            }
        }
        
        
    char zapros[2048];

        
    char forma[40] = "";

        
    sprintf(forma, "app/%d", index);

        
    strcpy(zapros,"GET /");
        
    strcat(zapros, forma);
        
    strcat(zapros," HTTP/1.1\nHost: ");
        
    strcat(zapros, HOST);
        
    strcat(zapros,"\nUser-agent: ");
        
    strcat(zapros,"Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.8) Gecko/2009032609 )");
        
    strcat(zapros,"\nAccept: */*\n\n");

        
        if (!
    bConnected)
        {
            
    printf( "Cannot connected\n" );

            return 
    FALSE;
        }
        else
        {
            
    // Send the magic http request
            
    if (send(hSocket, zapros, strlen(zapros), 0) == SOCKET_ERROR)
                return 
    FALSE;


            
    fd_read.fd_array[0] = hSocket; fd_read.fd_count = 1;
            
    fd_error.fd_array[0] = hSocket; fd_error.fd_count = 1;

            
    char otvet[1] = "";

            while (
    select(0, &fd_read, 0, &fd_error, &timeout) > 0)
            {
                if (
    fd_read.fd_count > 0)
                {
                    
    int nNumRead = recv(hSocket, otvet, 9216, 0);
                    
                    if (
    nNumRead <= 0)
                        break;
                }
                else
                {
                    break;
                }
            }

            
    char *found;
            
    found = strstr (otvet,"200");

            if (
    found)
            {
                
    char *nachalo = strstr (otvet,"<title>");

                
    char *conec = strstr (otvet,"</title>");

                
    int sizetitle = strlen(nachalo) - strlen(conec);

                
    char pretitle[1] = "";


                if ( 
    nachalo )
                {            
                                
                    
    strncat (pretitle, nachalo, sizetitle);    

                    
    mstudiodata_t *Hdr = ( mstudiodata_t * )pretitle;


                    
    char *steam = strstr (Hdr->c,"on Steam");

                    if( 
    steam )
                    {

                        
    int gamelen = strlen(Hdr->c) - strlen(steam);

                        
    char title[1] = "";


                        
    strncat (title, Hdr->c, gamelen);

                        
    printf( "Game: %s ID: %d\n", title, index );

                        
    fprintf( fp, "Game: %s ID: %d\n", title, index );


                    }

                    else
                    {
                        
    printf( "Game: %s ID: %d\n", Hdr->c, index );

                        
    fprintf( fp, "Game: %s ID: %d\n", Hdr->c, index );

                    }


                }


            }

        }

        
    closesocket(hSocket);
        
        }

        
    fclose(fp);


        return 
    TRUE;
    }

     
  2. Irdis

    Irdis Elder - Старейшина

    Joined:
    6 Feb 2006
    Messages:
    248
    Likes Received:
    52
    Reputations:
    3
    функция recv читает столько данных сколько пришло (у тебя не больше 9216),
    то есть тебе отправляют x данных, но вполне возможно nNumRead совсем не будет равняться x;
    и надо писать что-то в духе
    т. е. пока не дойдёт всё то, что ты запросил, ты будешь крутиться в цикле
     
    #2 Irdis, 8 Jun 2009
    Last edited: 8 Jun 2009
    1 person likes this.
  3. razb

    razb Active Member

    Joined:
    24 Mar 2009
    Messages:
    658
    Likes Received:
    133
    Reputations:
    18
    Внеси строку
    в блок
    тогда будет идти проверка после поиска тега в странице. Программа выпадала потому что при не нахождении тега в strlen передавался null.
     
    1 person likes this.
  4. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    Irdis, а разве имеет значение сколько пришло, я думал что главное что бы размер был не выше 9216, вроде бы если он будет меньше это не фатально

    может проще увеличить 9216 ?
     
  5. Irdis

    Irdis Elder - Старейшина

    Joined:
    6 Feb 2006
    Messages:
    248
    Likes Received:
    52
    Reputations:
    3
    recv
    дожидается прихода первого байта, и дальше считывает не больше 9216 и идёт дальше
    как проверить что она ложится именно в этом месте, да просто вывести в фаил то что пришло, и тогда можно много чего понять....
    Если тебя не устраивает критерий по размеру, то можно считывать пока ты не увидишь конец сообщения или что-то ему подобное.

    Реально сам долго тупил отсылал 15000 байт по сети, и прога сразу ложилась, потом проверил сколько пришло, было примерно 7000. А так когда сервер и клиент стоял на одном компе всё чудесно работало (под XP).
     
    #5 Irdis, 8 Jun 2009
    Last edited: 8 Jun 2009
  6. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    Всем спасибо, работает

    сейчас дам плюсы