Reputation: 962
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);
Upvotes: 2
Views: 156
Reputation: 70206
If there is no data ready, recv
will block or fail (depending on whether it's blocking or non-blocking).
recv
returns 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: close
to 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.
Upvotes: 1
Reputation: 25828
Because you are asking the socket to read BUFSIZE
data when there is no more to read. I'm assuming that the call to read
blocks waiting for more data to come across the TCP connection and will only return when the connection goes down some time later.
If you know how big the file is then you can request that only that amount of data is read. If you don't know how big the file is then you are relying on the server to close the connection when the file has been transferred.
Upvotes: 1