By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,602 Members | 1,473 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,602 IT Pros & Developers. It's quick & easy.

multiple forks in one client connection (ftpclient)

P: 2
Hi,
I am new to socket programming, I wrote an ftpclient which connects to an ftp server and downloads a file to the client computer.
Now in one client connection I want to download multiple files by forking the parent connection.
So far I have this, the code downloads only one file, and then gives the following error
"Transfer Completed425 Unable to build data connection: Invalid argument"

Appreciate if someone can help me here.
The code is a bit messy however it works for downloading a single file from the ftp server
Expand|Select|Wrap|Line Numbers
  1. /*******************************************************************************
  2. Object:        This is a ftp client which communicates with a ftp server
  3.         on port 21 (ftp-data port 20 RFC 959)
  4. Input:        IPAddress to connect to / username & password to connect to ftp server
  5.         filename to be downloaded (with path if not in the ftp directory of the user)
  6. Functioning:    Creates a ftp socket
  7.         A connection is established with the ftp server at the ip addr. and port 21 
  8.         After the connection is established user authentication is done with server 
  9.         and response is received.
  10.         Once the user is authenticated a request to download the specified file is sent to the ftp server
  11. Output:        None (though specified file is downloaded to the client machine).
  12.  
  13. ********************************************************************************/
  14. #include <stdio.h>        /* for printf() and fprintf() */
  15. #include <sys/socket.h>   /* for socket(), connect(), send(), and recv() */
  16. #include <arpa/inet.h>    /* for sockaddr_in and inet_addr() */
  17. #include <stdlib.h>       /* for atoi() */
  18. #include <string.h>       /* for memset() */
  19. #include <unistd.h>       /* for close() */
  20. #include <netdb.h>
  21. #include <errno.h>
  22. #include <sys/wait.h>
  23. #include <signal.h>
  24. #include "ftpClient1.h"
  25. #define RCVBUFSIZE 32     /* Size of receive buffer */
  26.  
  27. void DieWithError(char *errorMessage);    /* Error handling function */
  28. int ftpSendFile(char * buf, char * host, int port);
  29. int ftpRecvResponse(int sock, char * buf);
  30. int ftpNewCmd(int Sock, char * buf, char * cmd, char * param);
  31. int ftpConvertAddr(char * buf, char * hostname, int * port);
  32. void debug(int debugLevel, const char * debugDesc, const char * debugStr);
  33. /************************************
  34. for collecting zoombie processes
  35. *************************************/
  36.  
  37. void sigchld_handler(int s)
  38. {
  39.     while(waitpid(-1, NULL, WNOHANG) > 0);
  40. }
  41.  
  42. int main(int argc, char *argv[])
  43. {
  44.     int sock, clntSock;                                                                /*  Socket descriptor */
  45.     //int dataSock;                                                            /* Data sockeet Descriptor*/
  46.     int i;
  47.     int processID;
  48.     struct sockaddr_in ftpServAddr;                                            /*  server address */
  49.     struct hostent *hp;
  50.     unsigned short ftpServPort;                                                /*  server port */
  51.     char *servIP;                                                            /*  Server IP address */
  52.     char *username;                                                            /* User Name for ftp server */
  53.     char *pwd;                                                                /* Password for connecting to ftp server*/
  54.     char *fileName;                                                            /*  FileName to get from the server */
  55.     char *command;
  56.     char *file;
  57.     char *p;
  58.     char *c;
  59.     char *path;
  60.     int count;
  61.     char echoBuffer[RCVBUFSIZE];                                            /* Buffer for echo string */
  62.     unsigned int echoStringLen;                                                /* Length of string to echo */
  63.     int bytesRcvd, totalBytesRcvd;                                            /* Bytes read in single recv()*/
  64.     ftpServPort = 21;
  65.     char tmpHost[100];
  66.     int tmpPort;
  67.     char buf[5120];
  68.      unsigned int PORTBUFFER;
  69.      char * hostname;
  70.      servIP = argv[1] ;    /* First arg' server IP address */                
  71.  
  72.       /* Second arg' Username */
  73.       username = argv[2];
  74.                                                           /* Third arg' Password */
  75.       pwd =  argv[3];
  76.       printf("Creating Socket");
  77.       //debug(1, "Creating Socket", "");
  78.        struct sigaction sa; /* deal with signals from dying children! */
  79.        int yes = 1;
  80.  
  81.       if (argc< 4) /* Test for correct number of arguments */
  82.         {
  83.             fprintf(stderr, "Usage: %s <Server IP> <UserName> <Password> <File-to-download> \n",
  84.             argv[0]);
  85.             exit(1);
  86.         }
  87.  
  88.        gethostname(hostname, PORTBUFFER);
  89.  
  90.     /* Create a reliable, stream socket using TCP */
  91.     if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
  92.           DieWithError(" socket () failed") ;
  93.  
  94. /* Construct the server address structure */
  95.     memset(&ftpServAddr, 0, sizeof(ftpServAddr));                            /* Zero out structure */
  96.     ftpServAddr.sin_family         = AF_INET;                                /* Internet address family */
  97.     ftpServAddr.sin_addr.s_addr     = inet_addr(servIP);                    /* Server IP address */
  98.     ftpServAddr.sin_port           = htons(ftpServPort);                    /* Server port */
  99.  
  100. /* Establish the connection to the ftp server */
  101.         if (connect(sock, (struct sockaddr *) &ftpServAddr, sizeof(ftpServAddr)) < 0)
  102.            DieWithError(" connect () failed") ;
  103.         else
  104.       printf("Connection Successful");
  105.  
  106.     //sleep(1);
  107.     if(ftpRecvResponse(sock,buf)==1) 
  108.      {
  109.           printf("Reached Here");
  110.       if(strncmp(buf,"220",3)==0) 
  111.        {
  112.         printf("Sending UserName");
  113.         printf(username);
  114.         if(ftpNewCmd(sock,buf,"USER",username)==1);
  115.          {
  116.           if(ftpRecvResponse(sock, buf) == 1)
  117.              {
  118.              if(strncmp(buf,"331",3)==0)
  119.              {
  120.                  printf("Sending Password");
  121.                if(ftpNewCmd(sock, buf, "PASS", pwd) == 1)
  122.                  {
  123.                    if(ftpRecvResponse(sock, buf) == 1)
  124.                     {
  125.                       if(strncmp(buf, "230",3)==0)
  126.                        {
  127.  
  128.                 for(i=1; i<(argc-3);i++)
  129.                 {
  130.                 fileName = argv[3+i];
  131.                 if ((processID = fork()) < 0)
  132.                 {
  133.                  DieWithError("HERE");
  134.                  }
  135.                 else if(processID == 0)//this is the child
  136.                  {
  137.                                    if(ftpNewCmd(sock, buf, "PASV", "") == 1)
  138.                        {
  139.                                      if(ftpRecvResponse(sock, buf) == 1)
  140.                                       {
  141.                                       if(strncmp(buf, "227",3)==0)
  142.                                     {
  143.                     ftpConvertAddr(buf,tmpHost,&tmpPort);
  144.                     if(ftpNewCmd(sock,buf,"RETR",fileName)==1)
  145.                     {
  146.  
  147.                      ftpSendFile(fileName,tmpHost,tmpPort);
  148.                      if(ftpRecvResponse(sock,buf)==1)
  149.                      {
  150.                       if(strncmp(buf,"150",3)==0)
  151.                       {
  152.                        if(ftpRecvResponse(sock, buf)==1)
  153.                        {
  154.                                             printf("\nReceive Response\n");
  155.                        if(strncmp(buf,"226",3)==0)
  156.                        {
  157.                          printf("Transfer Completed");
  158.                         //close(sock);
  159.                          //exit(0);
  160.                        }
  161.                            }
  162.                                 }
  163.                                     }
  164.                                 }
  165.                          }
  166.                        }
  167.                      }
  168.                    }
  169.                 else //this is the parent process
  170.                  {
  171.                        /* Signal handler stuff */
  172.                        sa.sa_handler = sigchld_handler;
  173.                        /* reap all dead processes */
  174.                        sigemptyset( &sa.sa_mask);
  175.                        sa.sa_flags = SA_RESTART;
  176.                        if( sigaction( SIGCHLD, &sa, NULL) == -1)
  177.                         {
  178.                            perror( "Server sigaction");exit( 1);
  179.                           }
  180.                    }
  181.                   }    
  182.                       }     
  183.                       }
  184.                    }
  185.                       }
  186.                  }
  187.                 }
  188.                }
  189.               }    
  190. /* ToDo: Put Code for writing file stats(size, name, time taken to download etc)*/
  191.  
  192.     close(sock);
  193.       exit(0);
  194. }
Thanks,
Jul 10 '08 #1
Share this Question
Share on Google+
3 Replies


gpraghuram
Expert 100+
P: 1,275
If u are forking to create a child then you should wait in the parent process, till the child completes and returns.
Introduce wait call in the parent process and check how it goes.

raghuram
Jul 10 '08 #2

P: 2
If u are forking to create a child then you should wait in the parent process, till the child completes and returns.
Introduce wait call in the parent process and check how it goes.

raghuram
Hi,
Thanks for the prompt reply.
I am already doing what you suggested
Expand|Select|Wrap|Line Numbers
  1. code snippet from earlier post
  2.  
  3. #
  4. else //this is the parent process
  5.                  {
  6.                     /* Signal handler stuff */
  7.                  sa.sa_handler = sigchld_handler;
  8.                  /* reap all dead processes */
  9.                  sigemptyset( &sa.sa_mask);
  10.                  sa.sa_flags = SA_RESTART;
  11.                  if( sigaction( SIGCHLD, &sa, NULL) == -1)
  12.                   {
  13.                          perror( "Server sigaction");exit( 1);
  14.                           }
  15.  
  16.  
Can you advise if I am doing it at the right place.

Thanks,
Jul 10 '08 #3

gpraghuram
Expert 100+
P: 1,275
I am not very sure that this will wait for the child process to exit.
Why cant u use wait call instead of this...

Raghu
Jul 11 '08 #4

Post your reply

Sign in to post your reply or Sign up for a free account.