0

My code is too long to post all here so i'm going to sum up what's wrong.

In a server part i'm sending on a socket 3 things :

  • A message

  • The content of a file

  • Another message

In a client part i'm receiving these things but :

  • This first is to print on terminal

  • The second to write in a new file

  • The last to print on the terminal too

But my client is stuck on a read and i really don't know why. I'm on the problem for hour so if someone can help me, it will be very great !

edit : Basically, i think my problem is that i don't know what to write on the server to stop the read on the client.. Is it \n, \0.. ?

Here's the 2 part of code :

server

void    send_content(t_server *s, FILE *fd, int rfd)
{
  int   len;
  char  *buff;

  write(s->socket, "150 File status okay;"             \
         "about to open data connection.\n\0", strlen("150 File status okay;about to open data connection.\n\0"));
  fseek(fd, 0, SEEK_END);
  len = ftell(fd);
  buff = malloc(len * sizeof(char));
  read(rfd, buff, len);
  write(s->socket, buff, len);
  write(s->socket, "\n\0", strlen("\n\0"));
  write(s->socket, "226 Closing data connection.\n\0", strlen("226 Closing data connection.\n\0"));
  free(buff);
}

client

void    getfile(t_client *c, char **tab)
{
  int   ret;
  int   fd;
  int   z;
  char  buff[4096];

  z = 0;
  read(c->fd, buff, 4096);
  write(1, buff, strlen(buff));
  if (strlen(buff) < 25)
    return ;
  fd = creat(tab[1], S_IRUSR | S_IWUSR);
  while (z == 0 && (ret = read(c->fd, buff, 4096)) > 0)
    {
      if (ret < 4096)
        z = -1;
      write(fd, buff, strlen(buff));
      memset(buff, '\0', 4096);
    }
  read(c->fd, buff, 4096); // Stuck here
  write(1, buff, strlen(buff));
  close(fd);
}
nookonee
  • 871
  • 2
  • 8
  • 19

2 Answers2

0
  char  buff[4096];

  z = 0;
  read(c->fd, buff, 4096);
  write(1, buff, strlen(buff));

You should be saving the return value of the call to read(), in order to find out how many bytes you just received. You may have to make several calls to read() in order to get the entire message. It's wrong to use strlen() to find out how many bytes were received, because the buffer contents are uninitialized, and the first chunk of the message could be cut off anywhere, so you can't count on it being null-terminated.

Jim Lewis
  • 43,505
  • 7
  • 82
  • 96
0

Like noted you need a read function like this to make sure you receive specified number of bytes(this function will loop till it receives number of bytes it was told to). Just use this receivall method instead of read everywhere. With files you typically first send the file length, and then receive the file. I did something similar while ago, hope it will help you a bit. This is the client side, which tries to receive first file length from the server, then the file:

        /* create file */
        FILE * ptrMyFile = fopen(&filenames[i][0],"wb");
        if(NULL == ptrMyFile)
        {
            printf("Unable to open file \n");
            return 1;
        }

        int size = 0;
        int t = 4;

        /* first receive file size from server */
        /* NOTE: error checking is omitted from code, nevertheless users should stil do some error checking when using this code */
        readall(sockfd, (unsigned char*) &size, &t);

        /* how many 256 byte chunks are there? */
        int div = size / 256;

        /* loop to receive each chunk. */
        for(int k = 0; k < div; k++)
        {
            int chunk_size = 256;

            /* make sure we receive 256 bytes */
            readall(sockfd, buffer, &chunk_size);

            /* write to file */
            fwrite(buffer, chunk_size, 1, ptrMyFile);
        }

        /* read the final chunk. */
        int whatsleft = size - 256 * div;
        readall(sockfd, buffer, &whatsleft);

        /* write */
        fwrite(buffer, whatsleft, 1, ptrMyFile);

        /* close file */
        fclose(ptrMyFile);

I leave the server part to you.

Community
  • 1
  • 1
Giorgi Moniava
  • 27,046
  • 9
  • 53
  • 90