【发布时间】:2013-09-01 20:39:24
【问题描述】:
注意:这是一个家庭作业项目,我会尝试编写剩下的代码,但无法弄清楚为什么无法连接到输入 URL。
我得到了一些骨架代码,我对其进行了一些修改以接收输入 URL。预期用法可能是:./a.out http://google.com
无论出于何种原因,它都无法成功连接。始终打印错误消息“无法连接”。稍后我需要从 URL 中获取一个文件并将其保存到本地目录,但我会尝试弄清楚如何做到这一点(我的猜测是它与下面代码中的 recv() 有关)。在“http://google.com”的情况下,我应该使用“index.html”。
骨架代码使用connect(),但getaddrinfo() 的手册页使用bind(),这似乎要快得多,但也不起作用。使用 connect() 它似乎永远不会离开 for 循环(编辑:它永远不会离开,因为它似乎在尝试连接时卡住了):
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv) {
// Alex: Input usage (expecting one URL)
if (argc != 2) {
printf("Usage: ./hw1 URL\n");
exit(1);
}
// Alex: Set noHttp as argv[1] and remove "http://"
char* noHttp = argv[1];
char http[] = "http://";
if (strlen(noHttp) > 7 && !strncmp(noHttp, http, 7)) noHttp += 7;
else {
printf("Invalid URL, expecting http://host/path\n");
exit(1);
}
printf("%s\n", noHttp);
struct addrinfo hints;
struct addrinfo* result, * rp;
int sock_fd, s;
// Alex: I moved assigning hints.ai_socktype after memset()
memset(&hints, 0, sizeof(struct addrinfo));
//hints.ai_socktype = SOCK_STREAM;
s = getaddrinfo(noHttp, "8080", &hints, &result); // To Stack Overflow: This changed to "80", I am leaving it here because there are comments about it
if (0 != s) {
perror("Error populating address structure");
exit(1);
}
int i = 0;
for (rp = result; rp != NULL; rp = rp->ai_next) {
printf("i = %d\n", i);
i++;
//printf("rp->ai_flags = %d\n", rp->ai_flags);
printf("rp->ai_family = %d\n", rp->ai_family);
printf("rp->ai_socktype = %d\n", rp->ai_socktype);
printf("rp->ai_protocol = %d\n", rp->ai_protocol);
sock_fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
printf("sock_fd = %d\n", sock_fd);
if (sock_fd == -1) continue;
// Success
if (connect(sock_fd, rp->ai_addr, rp->ai_addrlen) != -1) break;
close(sock_fd);
}
if (rp == NULL) {
fprintf(stderr, "could not connect\n");
exit(1);
}
freeaddrinfo(result);
char buf[255];
memset(&buf, 0, sizeof(buf));
int recv_count = recv(sock_fd, buf, 255, 0);
if (recv_count < 0) {
perror("Receive failed");
exit(1);
}
printf("%s",buf);
shutdown(sock_fd, SHUT_RDWR);
return 0;
}
编辑:我按照 Uku Loskit 的建议将 "8080" 替换为 "80"。
【问题讨论】:
-
连接本地服务时对我来说很好。当您的任何系统调用返回错误时,您应该访问
errno并打印出错误消息,否则您将永远不知道哪里出错了。 -
为什么会发现 8080 端口是开放的? HTTP 的默认值为 80。
-
我不知道,我对此很陌生。我试图在网上查找8080和80之间的差异,但不明白。它最初有
"::1和"8080" -
::1只是localhost的 IPv6 简写。它所说的“最初”无关紧要,如果您不尝试连接到您不知道应该可用的服务,那么难怪它不起作用。 -
谢谢,我改了,还是不行
标签: c getaddrinfo