尝试下载流时,getaddrinfo()失败

时间:2020-11-12 12:02:58

标签: c sockets url getaddrinfo

我正在尝试使用套接字从实时流下载几秒钟。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* close() */
#include <sys/socket.h>
#include <netdb.h>

int main(void)
{
    int sock;
    char host[] = "http://141.138.89.176/fun-1-44-128";
    char port[] = "80";
    struct addrinfo hints, *res;
    char message[] = "GET / HTTP/1.1\nHost: http://141.138.89.176/fun-1-44-128";
    unsigned int i;
    char buf[1024];
    int bytes_read;
    int status;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    status = getaddrinfo(host, port, &hints, &res);
    if (status != 0) {
        perror("getaddrinfo");
        return 1;
    }
    sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (sock == -1) {
        perror("socket");
        return 1;
    }
    status = connect(sock, res->ai_addr, res->ai_addrlen);
    if (status == -1) {
        perror("connect");
        return 1;
    }
    freeaddrinfo(res);
    send(sock, message, strlen(message), 0);

    do {
        bytes_read = recv(sock, buf, 1024, 0);
        if (bytes_read == -1) {
            perror("recv");
        }
        else {
            printf("%.*s", bytes_read, buf);
        }
    } while (bytes_read > 0);

    close(sock);

    return 0;
}
  

代码会编译,但是运行时getaddrinfo()会失败。我认为这意味着找不到主机。

这是我的网址:http://141.138.89.176/fun-1-44-128 它可以在我的浏览器中工作,所以我不知道发生了什么。有人可以阐明这个问题吗?

2 个答案:

答案 0 :(得分:2)

我在我的环境中测试了您的代码,它可以正常工作,因此您的代码肯定可以。我建议检查编译器,或者重新安装。

编辑:好的,我想我发现了问题。只是主机应该是IP地址,而不是完整链接。

(还为getaddrinfo中的错误报告添加了修复程序)

    #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> /* close() */
#include <sys/socket.h>
#include <netdb.h>

int main(void)
{
    int sock;
    char host[] = "141.138.89.176";
    char port[] = "80";
    struct addrinfo hints, *res;
    char message[] = "GET / HTTP/1.1\nHost: 141.138.89.176/fun-1-44-128";
    unsigned int i;
    char buf[1024];
    int bytes_read;
    int status;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    status = getaddrinfo(host, port, &hints, &res);
    if (status != 0) {
    printf("Code: %d\n", status);
    printf("Message: %s\n", gai_strerror(status));
        return 1;
    }
...

答案 1 :(得分:1)

好,我想出了解决办法。

getaddrinfo() 接受具有子目录的基本主机名,域名或IP地址。

这意味着192.168.0.4,www.site.com,localhost均有效。 192.168.0.4/Search、www.site.com/Search、localhost/Search不是。

您也不需要包括该方案。套接字不会将http与https区别开来,这是处理请求的方式的区别。

您需要更改host,使其仅包含IP地址。

您想要的是:

char host[] = "141.138.89.176";

您现在不会收到该错误。

如果要访问子目录,则将其作为GET请求传递。实际上是处理文件和目录内容的Web服务器。基本IP保持不变。

首先,您的格式错误。完成后应该是\r\n\r\n\n\n。它应该看起来像这样:char message[] = "GET / HTTP/1.1\r\nHost: 141.138.89.176/fun-1-44-128\r\n\n\n";

现在,如果您尝试此操作,将出现400错误。这是因为写错了。类似于上述Host仅接受基本url / ip。在/之后看到GET吗?在那您可以请求任何想要的子目录/文件。您现在在那里的/表示您需要顶级字典。

它应该像这样:

message[] = "GET /fun-1-44-128 HTTP/1.1\r\nHost: 141.138.89.176\r\n\n\n";