我有一个简单的程序,它使用unix套接字从服务器下载html文件。
我使用write()发送“Get /index.html Host: * ”消息,然后使用while循环来读取() 响应。一切顺利,但最后一次读取()将返回0需要很长时间才能返回。任何想法纠正代码,以便我不必等待这个特殊的时间?或者这怎么可能发生?
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);
答案 0 :(得分:1)
因为您要求套接字在没有更多内容时读取BUFSIZE
数据。我假设调用read
阻塞等待更多数据通过TCP连接,并且只有在连接断开一段时间后才会返回。
如果你知道文件的大小,那么你可以请求只读取那么多的数据。如果您不知道文件有多大,那么您在依赖服务器在文件传输时关闭连接。
答案 1 :(得分:1)
如果没有准备好数据,recv
将阻止或失败(取决于它是阻止还是非阻塞)。
当套接字的另一端关闭连接时,recv
返回零。从来没有。
这通常不会发生在HTTP / 1.1(现在几乎所有现有服务器)上,至少不会立即发生,因为默认情况下连接预计会保持活动状态。
发送Connection: close
向服务器发出您不希望出现此行为的信号。然后它应该尽快放弃连接(但是当你发送所有内容之后)。
或者,您可以尝试调用shutdown(sockfd, SHUT_WR);
,它会执行连接的半关闭,以及服务器可能(应该,希望)对此做出适当反应。
或者,最后,您只能阅读内容长度告诉您的内容,然后删除连接,但这对服务器来说是反社会的,并且完全没有风险。