尝试下载流时 getaddrinfo() 失败
getaddrinfo() fails when attempting to download a stream
我正在尝试使用套接字从直播中下载几秒钟。
#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()
失败时。我假设这意味着找不到主机。
这是我的url:http://141.138.89.176/fun-1-44-128
它在我的浏览器中工作,所以我不知道发生了什么。谁能阐明这个问题?
我在我的环境中测试了您的代码,它运行良好,因此您的代码肯定没问题。我建议检查你的编译器,也许重新安装它。
编辑:好的,我想我找到了问题所在。就是host应该只是ip地址,而不是完整的link.
(还修复了 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;
}
...
好的,我找到了解决方案。
getaddrinfo()
仅 接受基本主机名、域名或 ip 地址,无 子目录。
这意味着192.168.0.4、www.site.com, localhost are all valid. 192.168.0.4/Search, www.site.com/Search、localhost/Search都不是。
您也不需要包含该方案。套接字不会区分 http 和 https,区别在于处理请求的方式。
您需要更改 host
以便它只包含 IP 地址。
你想要的是:
char host[] = "141.138.89.176";
您现在不会收到该错误。
如果您想访问一个子目录,您可以将其作为 GET
请求传递。它实际上是处理文件和目录内容的网络服务器。基本 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
之后的 /
了吗?这就是您请求任何 subdirectories/files 的地方。 /
你现在有表明你想要顶级词典。
它应该是这样的:
message[] = "GET /fun-1-44-128 HTTP/1.1\r\nHost: 141.138.89.176\r\n\n\n";
我正在尝试使用套接字从直播中下载几秒钟。
#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()
失败时。我假设这意味着找不到主机。
这是我的url:http://141.138.89.176/fun-1-44-128 它在我的浏览器中工作,所以我不知道发生了什么。谁能阐明这个问题?
我在我的环境中测试了您的代码,它运行良好,因此您的代码肯定没问题。我建议检查你的编译器,也许重新安装它。
编辑:好的,我想我找到了问题所在。就是host应该只是ip地址,而不是完整的link.
(还修复了 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;
}
...
好的,我找到了解决方案。
getaddrinfo()
仅 接受基本主机名、域名或 ip 地址,无 子目录。
这意味着192.168.0.4、www.site.com, localhost are all valid. 192.168.0.4/Search, www.site.com/Search、localhost/Search都不是。
您也不需要包含该方案。套接字不会区分 http 和 https,区别在于处理请求的方式。
您需要更改 host
以便它只包含 IP 地址。
你想要的是:
char host[] = "141.138.89.176";
您现在不会收到该错误。
如果您想访问一个子目录,您可以将其作为 GET
请求传递。它实际上是处理文件和目录内容的网络服务器。基本 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
之后的 /
了吗?这就是您请求任何 subdirectories/files 的地方。 /
你现在有表明你想要顶级词典。
它应该是这样的:
message[] = "GET /fun-1-44-128 HTTP/1.1\r\nHost: 141.138.89.176\r\n\n\n";