2

我编写了一个简单的程序,它使用 unix 套接字从服务器下载 html 文件。

我使用 write() 发送“Get /index.html Host: * ”消息,然后使用 while 循环读取()响应。一切顺利,但最后一个返回 0 的 read() 需要很长时间才能返回。有什么想法可以更正代码,这样我就不需要等待这个特殊的时间了吗?或者这怎么会发生?

    sprintf(cmdstr,"%s %s %s\r\nHOST:%s\r\n\r\n",METHOD,place,VERSION,host);
    cmdlen = strlen(cmdstr);
    if (write(sockfd,cmdstr,cmdlen) != cmdlen) {
       perror("write cmd error");
       return ;
    }

    while ((n = read(sockfd,read_data,BUFSIZE)) > 0) {
        read_data[n] = 0;
        p = read_data;

        if (filep == NULL) {
            if (filep = fopen(filename,"w")) == NULL) {
                perror("fopen ");
                return;
            }
            p = strstr(read_data,"\r\n\r\n");
            p += 4;
        }
        fputs(p,filep);
    }

    printf ("%s download completed.\n",filename);
4

2 回答 2

1

如果没有数据准备好,recv将阻塞或失败(取决于它是阻塞还是非阻塞)。当套接字的另一端关闭连接时
recv返回零。从来没有。

这通常不会发生在 HTTP/1.1(现在几乎所有现有服务器)中,至少不会立即发生,因为默认情况下连接应该保持活动状态。

向服务器发送一个Connection: close您不想要这种行为的信号。然后它应该尽快断开连接(当然,在向您发送所有内容之后)。

或者,您可以尝试调用shutdown(sockfd, SHUT_WR);,它执行连接的半关闭,并且服务器可能(应该,希望)做出适当的反应。

或者,最后,您只能阅读内容长度告诉您的内容,然后断开连接,但这对服务器来说有点反社会,而且并非完全没有风险。

于 2012-04-05T09:16:30.247 回答
1

因为您要求套接字在BUFSIZE没有更多要读取的数据时读取数据。我假设调用read阻塞等待更多数据通过 TCP 连接,并且只会在连接断开一段时间后返回。

如果您知道文件有多大,那么您可以请求只读取该数量的数据。如果您不知道文件有多大,那么您将依靠服务器在文件传输时关闭连接。

于 2012-04-05T08:46:03.153 回答