【问题标题】:C fgetc() on socket/file stream while checking for EOF goes into infinite loop检查 EOF 时套接字/文件流上的 C fgetc() 进入无限循环
【发布时间】:2012-10-26 08:28:57
【问题描述】:
int main(int argc, char *argv[]) {

    int conn_s = socket(AF_INET, SOCK_STREAM, 0);
    struct addrinfo hints;
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = 0;

    struct addrinfo *addr = (struct addrinfo *) calloc(1, sizeof(struct addrinfo));

    getaddrinfo("google.com", "80", &hints, &addr);

    connect(conn_s, addr->ai_addr, sizeof(struct sockaddr_in));

    char *http_request = "GET / HTTP/1.1\n\n";

    send(conn_s, http_request, strlen(http_request), 0);
    FILE *sockfile = (FILE *) fdopen(conn_s, "r");
    FILE *fp = fopen("/Users/leekaiwei/Desktop/results.html", "w+");
    int ch;

    while ((ch = fgetc(sockfile)) != EOF) {
        fprintf(fp, "%c", ch);
    }

    close(conn_s);
    fclose(fp);
    fclose(sockfile);
    free(addr);
    return 0;
}

while 循环永远不会结束。为什么是这样?我已经使用本地文件完成了此操作,并且工作正常。它也适用于 for 循环,只是 fgetc() 永远不会返回 EOF。

【问题讨论】:

  • http_request 中有错字 - 它应该以“\r\n\r\n”结尾。 http服务器是否有可能因为您的请求不完整而没有发送任何响应?这会让你的 fgetc 调用阻塞。
  • 是的,尝试检查例如tcpdump 或 wireshark 如果你收到来自服务器的回答...
  • 一旦您开始获取返回的数据,我认为您需要添加自己的代码来发现 http 响应的结尾,而不是假设 fgetc 将返回 EOF。如果服务器使您的连接保持活动状态,则较低级别的代码无法推断 EOF。
  • "while 循环永远不会结束。"我想你的意思是,fgetc“挂起”等待输入或EOF,而不是while循环不断滚动和打印字符?

标签: c loops eof infinite fgetc


【解决方案1】:

HTTP/1.1 默认为connection: keepalive,所以就像 simonc 说的,服务器实际上是在等待你发出下一个请求,并且会一直等到与服务器相关的超时。 使用HTTP/1.0 获取EOF

FWIW:完成需要 245 秒。

【讨论】:

  • 或者,将Connection: close 包含在 HTTP/1.1 标头中。而且,如果将此代码用于通用 HTTP 连接,请务必同时包含 Host: 标头,因为许多网站使用“命名虚拟主机”并需要该标头。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-11
  • 2019-03-05
  • 2012-06-18
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多