473,385 Members | 1,337 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

multiple forks in one client connection (ftpclient)

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
3 3459
gpraghuram
1,275 Expert 1GB
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
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
1,275 Expert 1GB
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

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

Similar topics

7
by: rdh | last post by:
Hi all, I am in process of developing a Server in C++ supporting multiple protocols. The server will be exposing various functionalities, and the clients can communicate over any of the...
11
by: Mike | last post by:
Looking to find any information on how to properly configure multiple instances of DB2. This is on Win2k db2 ver 7.2. I am basically looking for information on how the multiple instance settings...
9
by: Graham | last post by:
I have been having some fun learning and using the new Controls and methods in .Net 2.0 which will make my life in the future easier and faster. Specifically the new databinding practises and...
5
by: | last post by:
Hi all, HttpWebRequest, and SoapHttpClientProtocol both expose a ClientCertificates property, which can hold multiple client certificates, but on the service side, it can only receive one client...
2
by: jasonsgeiger | last post by:
From: "Factor" <jasonsgeiger@gmail.com> Newsgroups: microsoft.public.in.csharp Subject: Multiple Clients, One port Date: Wed, 19 Apr 2006 09:36:02 -0700 I'm been working with sockets for a...
3
by: D. Yates | last post by:
Hi, I'm about to embark on a project that will both send and receive information to/from our client computers in the field. The area that I still need to finalize is the method of...
35
by: keerthyragavendran | last post by:
hi i'm downloading a single file using multiple threads... how can i specify a particular range of bytes alone from a single large file... for example say if i need only bytes ranging from...
3
by: ZhukovL | last post by:
I'm having some trouble implementing the handling of multiple pipes in a shell I'm writing. I was hoping someone could point me in the right direction because I really cant see where I'm going...
4
by: Veeraraghavan | last post by:
Hi All, I am developing a client server communication using system.net.socket and I am finding it very difficult to get a solution for this. I started with single port communication with single...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.