简体   繁体   中英

Raw HTTP request with sockets getting “Resource temporarily unavailable”

I am trying to make a raw http request function using sockets in "C++". Everything worked good until i saw that i don't have timeout on that function, eg. when i do a request on an ip that don't have 80 open, it stays forever, so i decided to make a timeout, there fore instead using blocking sockets i started using non-blocking . There is that problem started. See the code bellow :

CODE :

size_t raw_http(char *host,char *ip, int port, char *page, char *content, size_t len)
{

    int sock;

    if(debug_super_http >= 5) puts("AAAA");
    // sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0)
    {
        if(debug_super_http >= 5) puts("BBBB");
        //printf("raw_http() ~ socket opening failed.\n");
        // exit(1);
        return 0;
    }

    perror("socket");

    struct sockaddr_in remote ;
    remote.sin_family = AF_INET;
    remote.sin_port = htons(port);
    remote.sin_addr.s_addr = inet_addr(ip);
    fd_set fdset;
    struct timeval tv;
    fcntl(sock, F_SETFL, O_NONBLOCK);

    if(debug_super_http >= 4) puts("CCCC");

    perror("socket");

    connect(sock,(struct sockaddr*)(&remote),sizeof(struct sockaddr_in));

    perror("socket");

    FD_ZERO(&fdset);
    FD_SET(sock, &fdset);
    tv.tv_sec = 10;
    tv.tv_usec = 0;

    if(select(sock + 1, NULL, &fdset, NULL, &tv) == 1)
    {
        int so_error;
        socklen_t len = sizeof so_error;
        getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);
        if (so_error == 0) 
        {
            //Is connected
            if(debug_super_http >= 4) puts("EEEE");

            perror("socket");
        }
        else
        {
            if(debug_super_http >= 4) puts("FFFF");

            perror("socket");

        }
    }
    else
    {       
        if(debug_super_http >= 4) puts("GGGGG");

        perror("socket");
    }

    /*
    if(debug_super_http >= 5) puts("33333");
    if(inet_pton(AF_INET, ip, (void *)(&(remote.sin_addr.s_addr))) <= 0)
    {
        //printf("raw_http() ~ inet_pton() failed.\n");
        // exit(1);
        return 0;
    }
    remote.sin_port = htons(port);
    */

    if(debug_super_http >= 5) puts("44444");

    perror("socket");

    /*
    if(connect(sock, (struct sockaddr *)&remote, sizeof(struct sockaddr)) < 0)
    {
        if(debug_super_http >= 5) puts("555555");
        //printf("raw_http() ~ socket connection failed.\n");
        // exit(1);
        return 0;
    }
    */

    if(debug_super_http >= 5) puts("666666");

    //build_get_query
    char *getpage = page;
    if(getpage[0] == '/') getpage = getpage + 1;
    char getcmd[4096];
    sprintf(getcmd, "GET /%s HTTP/1.0\r\nHost: %s\r\nUser-Agent: %s\r\n\r\n", getpage, host, USERAGENT);

    if(debug_super_http >= 5) puts("7777777");

    perror("socket");   

    size_t sent = 0;
    while(sent < strlen(getcmd))
    {
        if(debug_super_http >= 5) puts("8888888");

        perror("socket");

        ssize_t tmpres = send(sock, getcmd+sent, strlen(getcmd)-sent, 0);

        printf("tmpres=[%d]\n",tmpres);

        if(tmpres == -1)
        {
            // printf("raw_http() ~ http get command sending error.\n");
            if(debug_super_http >= 5) puts("8.5 8.5 8.5");
            // exit(1);
            return 0;
        }
        sent += tmpres;

        if(debug_super_http >= 5) puts("8.7 8.7 8.7");
    }

    if(debug_super_http >= 5) puts("9999999");

    perror("socket");

    char buf[8192];
    memset(buf, 0, 8192);
    // initialize html content buffer
    memset(content, 0, len);

    /*
    #if 0
        htmlcontent[0] = '\0';
        return 0;
    #endif
    */

    int htmlstart = 0; 

    printf("recv->[%d]\n",recv(sock, buf, 8192, 0));

    fprintf(stderr, "socket() failed: %s\n", strerror(errno));

    perror("socket");

    while(recv(sock, buf, 8192, MSG_WAITALL) > 0)
    {
        // if(debug_super_http >= 5) printf(">>> [%s]\n",buf);
        if(debug_super_http >= 5) puts("10 10 10");
        // receive max 1KB
        if(htmlstart == 0)
        {
            char *ptr = strstr(buf, "\r\n\r\n");
            if(ptr != NULL) 
            {
                htmlstart = 1;
                ptr += 4;
                strcat(content, ptr);
            } 
        }
        else
        {
            strcat(content, buf);
            break;
        }
        memset(buf, 0, 8192);
    }

    perror("socket");

    if(debug_super_http >= 5) printf(">>> CONTENT >>> [%s]\n",content);

    if(debug_super_http >= 5) puts("11 11 11");

    close(sock);

    if(debug_super_http >= 5) puts("12 12 12");

    perror("socket");

    return strlen(content);
}

I get the request on the http server, but i never get the response. Have tested it in browsers, wget, curl, seems the problem is that it is not entering the while(recv(sock, buf, 8192, 0) > 0) loop, but the request is being made. It gives me Resource temporarily unavailable basically.

OUTPUT :

AAAA
socket: Success
CCCC
socket: Illegal seek
socket: Operation now in progress
EEEE
socket: Illegal seek
44444
socket: Illegal seek
666666
7777777
socket: Illegal seek
8888888
socket: Illegal seek
tmpres=[133]
8.7 8.7 8.7
9999999
socket: Illegal seek
recv->[-1]
socket() failed: Resource temporarily unavailable
socket: Resource temporarily unavailable
socket: Resource temporarily unavailable
>>> CONTENT >>> []
11 11 11
12 12 12
socket: Resource temporarily unavailable

EDIT

puts(getcmd);

is :

GET /script.php?v=qqqqq HTTP/1.0
Host: 1.2.3.4
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; rv:2.2) Gecko/20110201

(here is /r/n/r/n probably)

Any hint?

Thank you!

i did a fcntl(sock, F_SETFL); after the if(select(sock + 1, NULL, &fdset, NULL, &tv) == 1) ... part and i still get no content

You may not omit the third arg of the fcntl(sock, F_SETFL, …) call; to remove the O_NONBLOCK flag, you can call fcntl(sock, F_SETFL, 0) .

In addition, you may not omit the second connect call after the non-blocking first connect yielded Operation now in progress , so remove the commenting around the second call.

Furthermore, the line

    printf("recv->[%d]\n",recv(sock, buf, 8192, 0));

already receives the first chunk of the web page content (or the entire content if small enough), but you discard what's in buf and don't display what was received.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM