I wirte a simple program that use unix sockets to download a html file from a server.
I use a write() to send “Get /index.html Host:*” message,and then use a while loop to read()
response. Everything goes well but the last read() which will return 0 takes a long time to return.Any idea to correct the code so that I need’t to wait for this special time? or how can this happened?
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);
If there is no data ready,
recvwill block or fail (depending on whether it’s blocking or non-blocking).recvreturns zero when the other end of the socket has closed the connection. Never otherwise.This does not normally happen with HTTP/1.1 (almost all existing servers today), at least not immediately, since connections are expected to be keep-alive by default.
Send a
Connection: closeto signal to the server that you do not want this behaviour. It should then drop the connection ASAP (but after sending you everything, of course).Alternatively, you can try calling
shutdown(sockfd, SHUT_WR);, which performs a half-close of the connection, and which a server might (should, hopefully) react to appropriately.Or, finally, you can only read as much as the content length tells you and then drop the connection, but that is kind of antisocial towards the server, and not entirely without risk.