Link to home
Start Free TrialLog in
Avatar of BeginToLearn
BeginToLearn

asked on

tranfer files

The idea is to transfer files from client to server. Here is my idea on how to implement it after i could establish connection between them.
   Client : . open a file
               . read to bufffer
               . send buffer
    Server: . receive buffer
                 . write to file
please advise . Now i gonna work on detals which will create a lot of problems :)
Avatar of Raheman M. Abdul
Raheman M. Abdul
Flag of United Kingdom of Great Britain and Northern Ireland image

SOLUTION
Avatar of Raheman M. Abdul
Raheman M. Abdul
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of BeginToLearn
BeginToLearn

ASKER

my code can communicate to each other already. So i gonna get some info from your link
 https://www.experts-exchange.com/questions/21285504/server-client-file-transfer-problem.html?sfQueryTermInfo=1+10+30+c+client+file+server+transfer
 to my code. hihi
Take a look at http://msdn.microsoft.com/en-us/library/ms737889 ("Running the Winsock Client and Server Code Sample") whiich contains links to both a complete server and client for that. If you are not targetting Windows, just omit the 'WSA'-prefixed calls and add the appropriate #include directives.
tks a lot for all reference. Now i need to work on it :)
while i work on my code, gcc keeps telling me i have bug at line "void sendFile(SOCKET sock)" with the message "error:expected ')' before 'sock'. Pls help me.

---
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>

#define PORT 3490

void error(const char *msg)
{
    perror(msg);
    exit(0);
}


bool sendFile(SOCKET sock)
{
     char cwd[1024];
       if (getcwd(cwd, sizeof(cwd)) != NULL)
           printf(stdout, "Current working dir: %s\n", cwd);
       else
           perror("getcwd() error");
   
     return true;
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];


    portno = PORT;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");

    server = gethostbyname("ubuntu");

    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;

    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);

    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");

   
    sendFile(sockfd);

    printf("Please enter the message: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0)
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0)
         error("ERROR reading from socket");
    printf("client: %s\n",buffer);
    int t;
      if(( t= close(sockfd))== -1)
            printf("t is %d\n",t);
    return 0;
}

Sorry, I forgot - add

typedef int SOCKET;

after your #include list.
after add
   typedef int SOCKET
after #include list, i still have
client.c:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘sendFile’
Hmm, you are compiling as C, not C++, are you? Then 'bool' is unknown to the compiler, also add

#ifndef __cplusplus__
typedef unsigned char bool;
#endif
i used to use VC++ compiler on windows. Now just move to linux so i get stuck. let me play around with it because after i add
  #ifndef __cplusplus__
typedef unsigned char bool;
#endif

it still complains bugs
Which errors are you getting now? BTW, VC++ would also compile a file with a .c extension as plain C.
now i am using g++ to compile it on ubuntu.
right now my function is

bool sendFile(SOCKET sock)
{

     char cwd[1024];
     string currentdir;
   
       memset ( cwd, '\0',sizeof(cwd));
       if (getcwd(cwd, sizeof(cwd)) != NULL)
      {
            currentdir = cwd;
           //printf(stdout, "Current working dir: %s\n", cwd);
           cout<<"Current working dir: "<<currentdir;

        }      
      else
           perror("getcwd() error");
 
     return true;
}
error message
client.c:34: error: ‘string’ was not declared in this scope
client.c:34: error: expected ‘;’ before ‘currentdir’
client.c:39: error: ‘currentdir’ was not declared in this scope
client.c:41: error: ‘cout’ was not declared in this scope

My purpose is to get the current directory then fiind one files at a time to read in buffer and send to server. It will repeat for whole directory.
Well, regarding 'string' and 'cout', you will need to add

#include <string>
#include <iostream>
using namespace std;
Thanks. NO bugs now.
I am able to read all files in a directory. I just wonder what kind of technique should i use to store those files before sending each of them to server? and how about subdirectory scenario? thanks a lot.

-------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <dirent.h>

#include <string>
#include <iostream>
using namespace std;

typedef int SOCKET;

#define PORT 3490



void error(const char *msg)
{
    perror(msg);
    exit(0);
}


int sendFile(SOCKET sock)
{

       char cwd[1024];
   
       memset ( cwd, '\0',sizeof(cwd));
       
        if (getcwd(cwd, sizeof(cwd)) != NULL)
      {
           printf("Current working dir: %s\n", cwd);
        }      
      else
           perror("getcwd() error");
     
        DIR *mydir = opendir(cwd);

        struct dirent *entry = NULL;
   
       while((entry = readdir(mydir)))
       {
            printf("%s\n", entry->d_name);
       }

    closedir(mydir);
 
     return 1;
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];


    portno = PORT;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");

    server = gethostbyname("ubuntu");

    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;

    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);

    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");

   
    sendFile(sockfd);

    printf("Please enter the message: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0)
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0)
         error("ERROR reading from socket");
    printf("client: %s\n",buffer);
    int t;
      if(( t= close(sockfd))== -1)
            printf("t is %d\n",t);
    return 0;
}

>> I just wonder what kind of technique should i use to store those files
>>before sending each of them to server?

Hm, not quite sure what you mean - since these files already exist on the disk, do you mean to copy them before sending them to the server? Seems kinda unnecessary to me. And regarding subdirectories, that you can do like
#include <sys/types.h>
#include <dirent.h>
#include <string>
#include <iostream>
using namespace std;

void list_all_files ( const string& sStartDir, list<string>& lstFound) {

   cout << "checking " << sStartDir.c_str () << endl;

   DIR* pDir = opendir ( sStartDir.c_str ());

   if ( !pDir) return false;

   dirent* pEntry;

   while ( pEntry = readdir ( pDir)) {

       cout << "found " << pEntry->d_name << endl;

       if ( DT_DIR & pEntry->d_type && strcmp ( pEntry->d_name, ".") && strcmp ( pEntry->d_name, "..")) {

           string sSubDir = sStartDir + string ( "/") + string ( pEntry->d_name);

           list_all_files ( sSubDir, sFound)) {

       }

       string sFound = sStartDir + string ( "/") + string ( pEntry->d_name);

       lstFound.push_back ( sFound);
   }
}

Open in new window

I think about big files which are maybe 500 mb or above. So I plan to try to send small packet at a time in order to make sure server could get all. The best to have a "resume" feature so when the connection get lost, it can continue from previous state.
 However, I have no idea. to use such as link list or vector or whatever. Please advise. thanks.
i think i need to focus on send files in this question only. about "resume" feature, i will open new question after this done. Thanks for your help.
Ah, I see what you mean - splitting them up in smaller chunks (~2KB) would usually be a good approach, e.g.
#include <sys/stat.h>

struct stat buf;

stat("/path/file.txt",&buf);

size_t sz = buf.st_size;

//...

char filechunk[2048];
size_t count = sz / 2048;
size_t remainder = sz % 2048;

for (unsigned i = 0; i < count; ++i) {

  // read 2048 bytes from file and send them
}

// read 'remainder' bytes from file and send them

Open in new window

wow you can read my mind. I gonna implement your idea. Thanks.
after i add the list_all_files() in my code, i have bugs with compiler.
Could you please help me on this? it bothers me a lot. I have tried both gcc and g++, fail.
PS: i use ubuntu on virtualbox
---

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <dirent.h>

#include <string>
#include <iostream>
using namespace std;

typedef int SOCKET;

#define PORT 3490



void error(const char *msg)
{
    perror(msg);
    exit(0);
}


void list_all_files ( const string& sStartDir, list<string>& lstFound) {

   cout << "checking " << sStartDir.c_str () << endl;

   DIR* pDir = opendir ( sStartDir.c_str ());

   if ( !pDir) return false;

   dirent* pEntry;

   while ( pEntry = readdir ( pDir)) {

       cout << "found " << pEntry->d_name << endl;

       if ( DT_DIR & pEntry->d_type && strcmp ( pEntry->d_name, ".") && strcmp ( pEntry->d_name, "..")) {

           string sSubDir = sStartDir + string ( "/") + string ( pEntry->d_name);

           list_all_files ( sSubDir, sFound)) {

       }

       string sFound = sStartDir + string ( "/") + string ( pEntry->d_name);

       lstFound.push_back ( sFound);
   }
}




int sendFile(SOCKET sock)
{

       char cwd[1024];
   
       memset ( cwd, '\0',sizeof(cwd));
       
        if (getcwd(cwd, sizeof(cwd)) != NULL)
      {
           printf("Current working dir: %s\n", cwd);
        }      
      else
           perror("getcwd() error");
     
       DIR *mydir = opendir(cwd);

       struct dirent *entry = NULL;
       while((entry = readdir(mydir)))
       {
            printf("%s\n", entry->d_name);
       }

    closedir(mydir);
 
     return 1;
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];


    portno = PORT;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");

    server = gethostbyname("ubuntu");

    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;

    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);

    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");

   
    sendFile(sockfd);

    printf("Please enter the message: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0)
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0)
         error("ERROR reading from socket");
    printf("client: %s\n",buffer);
    int t;
      if(( t= close(sockfd))== -1)
            printf("t is %d\n",t);
    return 0;
}

i really want to have a way to compile my code no matter c or c++. is there anyway of it?
What errors are you getting (my crystal ball is on repair)?
gcc -o client client.c
client.c:13: fatal error: string: No such file or directory
compilation terminated.
--> line 13 : include string


g++ -0 client client.c
g++: unrecognized option '-0'
client.c:30: error: ‘list’ has not been declared
client.c:30: error: expected ‘,’ or ‘...’ before ‘<’ token
client.c: In function ‘void list_all_files(const std::string&, int)’:
client.c:36: error: return-statement with a value, in function returning 'void'
client.c:48: error: ‘sFound’ was not declared in this scope
client.c:48: error: expected ‘;’ before ‘)’ token
client.c:54: error: ‘lstFound’ was not declared in this scope
client.c:62: error: a function-definition is not allowed here before ‘{’ token
client.c:141: error: expected ‘}’ at end of input


my crystal ball is on repair--> why?
You'r just missing an include file, make that

#include <string>
#include <iostream>
#include <list>
using namespace std;

Oh, and that should be '-o' and not '-0', i.e.

g++ -o client client.c
g++ -o client client.c
client.c: In function ‘void list_all_files(const std::string&, std::list<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’:
client.c:40: error: return-statement with a value, in function returning 'void'
client.c:52: error: ‘sFound’ was not declared in this scope
client.c:52: error: expected ‘;’ before ‘)’ token
client.c:66: error: a function-definition is not allowed here before ‘{’ token
client.c:145: error: expected ‘}’ at end of input

Still . The way i remember "o" is from "output" because sometimes i confuse between "o" and "0"
Ah, I see - change that to
void list_all_files ( const string& sStartDir, list<string>& lstFound) {

   cout << "checking " << sStartDir.c_str () << endl;

   DIR* pDir = opendir ( sStartDir.c_str ());

   if ( !pDir) return;

   dirent* pEntry;

   while ( pEntry = readdir ( pDir)) {

       cout << "found " << pEntry->d_name << endl;

       if ( DT_DIR & pEntry->d_type && strcmp ( pEntry->d_name, ".") && strcmp ( pEntry->d_name, "..")) {

           string sSubDir = sStartDir + string ( "/") + string ( pEntry->d_name);

           list_all_files ( sSubDir, sFound)) {

       }

       string sFound = sStartDir + string ( "/") + string ( pEntry->d_name);

       lstFound.push_back ( sFound);
   }
}

Open in new window

ubuntu@ubuntu:~/program$ gcc -o client client.c
client.c:14: fatal error: string: No such file or directory
compilation terminated.

^-^
Are you in the wrong directory? Hadn't you moved to g++?
i also tried this , but forgot to post

ubuntu@ubuntu:~/program$ g++ -o client client.c
client.c: In function ‘void list_all_files(const std::string&, std::list<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)’:
client.c:52: error: ‘sFound’ was not declared in this scope
client.c:52: error: expected ‘;’ before ‘)’ token
client.c:66: error: a function-definition is not allowed here before ‘{’ token
client.c:145: error: expected ‘}’ at end of input
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
no bugs , but it can't display all file names. I have no clude now hix hix
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <dirent.h>


#include <string>
#include <iostream>
#include <list>
using namespace std;



typedef int SOCKET;

#define PORT 3490



void error(const char *msg)
{
    perror(msg);
    exit(0);
}


void list_all_files ( const string& sStartDir, list<string>& lstFound) {

   cout << "checking " << sStartDir.c_str () << endl;

   DIR* pDir = opendir ( sStartDir.c_str ());

   if ( !pDir) return;

   dirent* pEntry;

   while ( pEntry = readdir ( pDir)) {

       cout << "found " << pEntry->d_name << endl;

       if ( DT_DIR & pEntry->d_type && strcmp ( pEntry->d_name, ".") && strcmp ( pEntry->d_name, "..")) {

           string sSubDir = sStartDir + string ( "/") + string ( pEntry->d_name);

           list_all_files ( sSubDir, lstFound) ;

       }

       string sFound = sStartDir + string ( "/") + string ( pEntry->d_name);

       lstFound.push_back ( sFound);
   }
}




int sendFile(SOCKET sock)
{

       char cwd[1024];
       list<string> myList;

       memset ( cwd, '\0',sizeof(cwd));
       
        if (getcwd(cwd, sizeof(cwd)) != NULL)
	{
           printf("Current working dir: %s\n", cwd);
        }       
	else
           perror("getcwd() error");
      
       //display all file names in dir and subdir
       DIR *mydir = opendir(cwd);
       
       struct dirent *entry = NULL;
       while((entry = readdir(mydir))) 
       {
            printf("%s\n", entry->d_name);
       }
       
     
       
       list_all_files ( cwd, myList);
       
       string::const_iterator p;      
       cout<<"myList begin: "<<myList.size();
       
       for(int i =0; i< myList.size();i++)
       {
            cout<<myList[i];
       }
      
      
       

    closedir(mydir);
  
     return 1;
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];


    portno = PORT;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");

    server = gethostbyname("ubuntu");

    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }

    bzero((char *) &serv_addr, sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;

    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);

    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");

    
    sendFile(sockfd);

    printf("Please enter the message: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);

    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0)
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0)
         error("ERROR reading from socket");
    printf("client: %s\n",buffer);
    int t;
	if(( t= close(sockfd))== -1)
		printf("t is %d\n",t);
    return 0;
}

Open in new window

it's weird, but it can display now. Initially it even displayed some files that's i can't find in directory hihi.
i am so happy now bc it can read all file names. Tomorrow I gonna work on transfer file.Tks a lot for your help .
is it ok to close this question here and open a new one about file transfer? because i don't want the question is too long.
Sure, no problems with that...