Multiple File Transfer using BSD socket

 I intended to implement multiple  file transfers in the Socket File transfer post : 

https://www.arupsarker.com/blog/file-transfer-using-bsd-socket  . If I did that, the whole post would be very long. The whole idea is to implement multiple file transfer with BSD socket, by using the previous code of file read/write mechanism at the server and client code. I will try to keep it short.

Here is the basic step: 

On the server side,

On the client side,



From the post, https://www.arupsarker.com/blog/file-transfer-using-bsd-socket , I have just included the accept and recv functions inside the while loop.


Server-side Changes:

We are creating a new connection from the client for each file. Although, it is not a good design. Later with concurrency, we will be able to overcome this design.


Anyway, for starting the basic transfer mechanism, we are good for now. 


while(1) { // Only these two read marked lines are added.

// 6. Accept connection for concurrency number

socklen_t adlen = sizeof(nwClientAddr);

int cfd = accept(sockfd, (struct sockaddr *) &nwClientAddr, &adlen);

if (cfd == -1) {

perror("Error in Accepting Connection for ");

exit(1);

}

// 7. Receive incoming file from client

char filename[MAX_NAME] = {0};


if (recv(cfd, filename, MAX_NAME,0) == -1) {

perror("Unable to receive file due to connection or file error");

exit(1);

}


int fileLength = strlen(filename);

if(fileLength > 0) {

// 8. After receiving from client, create file to save data


FILE *fp = fopen(filename, "wb");

if (fp == NULL) {

perror("Unable to create File pointer");

exit(1);

}

// 9. Start receiving file Data and print in console

char addr[INET_ADDRSTRLEN];

// 10. Write the data into file.

fileWriter(filename, cfd, fp);

// 11. Print success message into console

printf("%s is received\n",filename);

}

close(cfd);

}

Client Side changes:

At the client side, 

1. We have to read each file from the directory.

2. For each file, we are repeating the steps mentioned in the first part.


These are the newly added codes in the main function.

Inside the while loop for each file, we are calling red lines which was a single call in single file transfer.



char *dirName = basename(argv[1]);

if (dirName == NULL) {

perror("Unable to get dirName");

exit(1);

}

// 4. Read All the file list from directory


DIR *dirPtr = opendir (dirName);


// 5. validate directory open

if (!dirPtr) {

char errbuf[PATH_MAX] = "";

sprintf (errbuf, "opendir failed on '%s'", dirName);

perror (errbuf);

return EXIT_FAILURE;

}

printf("Directory name : %s\n", dirName);


struct dirent *dir;


int idx = 0;

char filePathList[MAX_FILE_COUNT][MAX_NAME] = {0};

char fileNameList[MAX_FILE_COUNT][MAX_NAME] = {0};

if(dirPtr!=NULL) {

int flag = 0;


while((dir=readdir(dirPtr))!=NULL) {

if((strcmp(dir->d_name,".")==0 || strcmp(dir->d_name,"..")==0 || (*dir->d_name) == '.' )){

}

else

{

// 6. Define and Initialize the Buffer


char buff[MAX_NAME] = {0};

char fileWithPath[MAX_NAME] = {0};


strcat(fileWithPath, dirName);

strcat(fileWithPath, "/");


strcat(fileWithPath, dir->d_name);


// 7. Copy the file name into Buffer

strncpy(buff, dir->d_name, strlen(dir->d_name));

sockUtil(argv[2], buff,fileWithPath); // This was a single call for single file transfer


printf("%s\n", fileWithPath);

idx++;

}

}

}

if(idx == 0) {

printf("There is no file in the directory : %s\n", dirName);

return 1;

         }


Prepare

$ git clone https://github.com/arupcsedu/BSDSocketProgramming.git

$ cd BSDSocketProgramming

Build and Run Server

$ cd SockMFileTransfer/Server

$ g++ Server.cpp -o Server

$ ./Server 

Build and Run Client

$ cd ..
$ cd Client
$ dd if=/dev/zero of=res/s1 bs=10MB count=1 //This is for creating 10MB file in res directory. Execute multiple times for creating multiple files.
$ g++ Client.cpp -o Client
$ ./Client res 127.0.0.1

Source code URL:

https://github.com/arupcsedu/BSDSocketProgramming