繁体   English   中英

带有套接字的原始HTTP请求“资源暂时不可用”

[英]Raw HTTP request with sockets getting “Resource temporarily unavailable”

我正在尝试使用“ C ++”中的套接字制作原始的http请求功能。 一切正常,直到我看到该功能没有超时,例如。 当我在没有打开80的ip上发出请求时,它永远存在,因此我决定进行超时,因此开始使用blocking套接字,而我开始使用non-blocking 问题开始了。 参见下面的代码:

代码:

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);
}

我在http服务器上收到了请求,但从未收到响应。 已经在浏览器中进行了测试,wget,curl,似乎问题在于它没有进入while(recv(sock, buf, 8192, 0) > 0)循环,但是正在发出请求。 它使我的Resource temporarily unavailable基本上Resource temporarily unavailable

输出:

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

编辑

puts(getcmd);

是:

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)

有什么提示吗?

谢谢!

我做了一个fcntl(sock, F_SETFL); if(select(sock + 1, NULL, &fdset, NULL, &tv) == 1) ...我仍然没有任何内容

您可能不会忽略fcntl(sock, F_SETFL, …)调用的第三个参数 要删除O_NONBLOCK标志,可以调用fcntl(sock, F_SETFL, 0)

此外,在非阻塞的第一个connect产生“ Operation”(正在进行操作)之后,您可能不会省略第二个connect呼叫,因此请删除第二个呼叫周围的注释。

此外,线

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

已经接收到网页内容的第一块(如果足够小,则接收全部内容),但是您将丢弃buf ,而不显示接收到的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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