thoughtful
thoughtful

Reputation: 11

Sending file (client to server and server to client)

I have client.c and server.c , I'm trying to send a file from client to server and from server to client... The file is received by the server but when the server sends the file , the client stops or does not receive the file , The sendFile() function:

void sendfile(int fd,char* filename)
{
    char buff[0x1000]; 
    FILE *file = fopen(filename, "rb"); 
    if (!file)
    {
        printf("Can't open file for reading"); 
        return;
    }
    while (!feof(file)) 
    { 
        int rval = fread(buff, 1, sizeof(buff), file); 
        if (rval < 1)
        {
            printf("Can't read from file\n");
            fclose(file);
            return;
        }

        int off = 0;
        do
        {
            int sent = send(fd, &buff[off], rval - off, 0);
            printf("Sending ...\n");
            if (sent < 1)
            {
                printf("Can't write to socket");
                fclose(file);
                return;
            }
            printf("[SendFile]Fisierul a fost trimis!\n");
            off += sent;
        }
        while (off < rval);
    } 
 fclose(file);
} 

The getFile():

void getFile(int fd,char* filename)
 {
    int rval; 
    char buff[0x1000]; 
    FILE *file = fopen(filename, "w+"); 
    if (!file)
    {
        printf("Can't open file for writing");
        return;
    }

    do
    {
        rval = recv(fd, buff, sizeof(buff), 0);
        if (rval < 0)
        {
            printf("Can't read from socket");
            fclose(file);
            return;
        }

        if (rval == 0)
            break;

        int off = 0;
        do
        {
            int written = fwrite(&buff[off], 1, rval - off, file);
        printf("[server]Writing %d bytes\n",written);
            if (written < 1)
            {
                printf("Can't write to file");
                fclose(file);
                return;
            }

            off += written;
        }
        while (off < rval);
    printf("[server]File received!\n"); 
    }  
    while(1);
    fclose(file); 
 }

The client main():

int main (int argc, char *argv[])
{
  int sd;
  struct sockaddr_in server;

  if (argc != 2)
    {
      printf ("[client] Sintaxa: %s <filename>\n", argv[0]);
      return -1;
    }

  if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
    {
      perror ("[client] Eroare la socket().\n");
      return errno;
    }

  server.sin_family = AF_INET;
  server.sin_addr.s_addr = inet_addr("127.0.0.1");
  server.sin_port = htons (port);

  if (connect (sd, (struct sockaddr *) &server,sizeof (struct sockaddr)) == -1)
    {
      perror ("[client]Eroare la connect().\n");
      return errno;
    }
    sendfile(sd,"test.cpp");
    printf("File sent\n");
    getFile(sd,"server.c");
    close (sd);
}

The loop from server.c

while (1)
    {
      int client;
      int length = sizeof (from);

      printf ("[server]Asteptam la portul %d...\n",port);
      fflush (stdout);

      client = accept (sd, (struct sockaddr *) &from, &length);

      if (client < 0)
      {
      perror ("[server]Eroare la accept().\n");
      continue;
      }

    if((pid=fork()) == 0 )
    {

    getFile(client,"test.cpp");
        sendfile(client,"server.c");
        printf("File sent\n");
    close(client);
  } 

 }

Upvotes: 1

Views: 1884

Answers (2)

cmidi
cmidi

Reputation: 2010

To Start with.

  1. accept(), connect(), recv() .. all are blocking calls so in theory your program can get blocked anywhere in these calls until you use non blocking sockets. From the program it looks like you are using blocking sockets

  2. I would suggest you to read a good socket programming tutorial like this one first https://beej.us/guide/bgnet/

Secondly

I would suggest you to have a tool like wireshark or any other packet analyzer tool running to debug your problem.

Lastly you can do something like the following code snippets to try

  1. Set sockets to non blocking mode using fnctl API call.

    int rc = fcntl(newFd, F_GETFL,0);
    rc |= O_NONBLOCK;
    rc = fcntl(newFd, F_SETFL,rc);
    
  2. Poll the socket for events You can use something like select,poll for the
    same. Here is a nice example for select in the Beej's tutorial. https://beej.us/guide/bgnet/html/multi/selectman.html

  3. Handle errors correctly. Non blocking sockets can return a EAGAIN or EWOULDBLOCK error which has to be handled correctly. The error means the socket is not readable or writable at the moment look for events and try again. Someting on the lines of.

      rval = recv(fd, buff, sizeof(buff), 0);
      if (rval < 0)
      {
           if((errno == EWOULDBLOCK)||(errno ==EAGAIN))
           {
               continue;
           }
           else
               //cleanup
       }
    

Upvotes: 3

thoughtful
thoughtful

Reputation: 11

tre problem was the do { ... } while(1); from getFile ...so I deleted the loop...

Upvotes: 0

Related Questions