user2467899
user2467899

Reputation: 575

send a file without waiting the reception of the whole file

I have a Server that contact another Server in order to obtain a file and then send it to the Client. I have write this piece of code (C - Linux) but only the first 4 bytes arrive to the Client. Someone better than me can see the mistake? Thank you very much

int Recv_file (int s, int f, char *ptr, size_t maxlen){
    int const TIMEOUT = 60; /* 60 seconds */
    size_t n;
    ssize_t nread;
    ssize_t nsend;
    char c;
    fd_set cset;
    struct timeval tval;
    int x;

    for (n=1; n<maxlen; n++)
    {
        FD_ZERO(&cset);
        FD_SET(s, &cset);
        tval.tv_sec = TIMEOUT;
        tval.tv_usec = 0;
        x = select(FD_SETSIZE, &cset, NULL, NULL, &tval);
        if (x==-1) {
            perror("select() failed");
            return -1; /* -1 = close connection with the client */
        }
        if (x>0) {
            nread=recv(s, &c, 1, 0);
            if (nread == 1)
            {
                *ptr++ = c;
                nsend = Send(f,&c,1);
                if (nsend != 1) {
                    return -1; /* close connection with the client  */
                }
            }else if (nread == 0){
                *ptr = 0;
                return (-1); /* close connection with the client  */
            }
            else
                return (-1); /* close connection with the client  */
        }else{
            printf("(It's been %d seconds and I have not received any response",TIMEOUT);
            close(s);
            return(-1); /* close connection with the client  */
        }
    }
    *ptr = 0;
    return (n); /* n == maxlen */
}

with:

int Send(int s, char *ptr, size_t nbytes){
    size_t  nleft;
    ssize_t nwritten;

    for (nleft=nbytes; nleft > 0; )
    {
        nwritten = send(s, ptr, nleft, 0);
        if (nwritten <=0)
            return (nwritten);
        else
        {
            nleft -= nwritten;
            ptr += nwritten;
        }
    }
    return (nbytes - nleft); /* number of bytes sent */
}

UPDATE:

While waiting for an answer I modified:

nread=recv(s, &c, 1, 0); in nread=recv(s, &c, sizeof(c), 0);

and

Send(f,&c,1); in Send(f,&c,sizeof(c));

But now I don't receive the last bytes of the file!

Thank you again!

Upvotes: 1

Views: 101

Answers (1)

ja_mesa
ja_mesa

Reputation: 1969

You don't get the last byte because the for loop start at 1

for (n=1; n<maxlen; n++); 
// it should be
for (n=0; n<maxlen; n++); 
// or either
for (n=1; n<=maxlen; n++); 

EDIT: Also, you could read as much bytes as are available not just one by one, in fact you are sending in the correct way,

For example:

int bLeft = maxlen;
while (bLeft > 0)
{
    FD_ZERO(&cset);
    FD_SET(s, &cset);
    tval.tv_sec = TIMEOUT;
    tval.tv_usec = 0;
    x = select(FD_SETSIZE, &cset, NULL, NULL, &tval);
    if (x > 0) {
         nread=recv(s, ptr, bLeft , 0);
         if (nread > 0)
         {
            nsend = Send(f, ptr, nread, 0);
            if (nsend <= 0) {
               return -1; /* close connection with the client  */
            }
            ptr+ = nread;
            bLeft -= nread;
        }else if (nread == 0){
             *ptr = 0;
             return (-1); /* close connection with the client  */
         }
         else
             return (-1); /* close connection with the client  */
   }else{
         printf("(It's been %d seconds and I have not received any response",TIMEOUT);
         close(s);
         return(-1); /* close connection with the client  */
   }
}
// I would not recommended this, you should adhere to a maxlen length
// assuming there is more space could lead to a memory Exception.
ptr++;
*ptr ='\0';
return (maxlen-bLeft);

Upvotes: 1

Related Questions