shellfly
shellfly

Reputation: 962

why the last read() takes a long time to return

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

Answers (2)

Damon
Damon

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

Nick
Nick

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

Related Questions