Search code examples
socketstcptcpclient

Sending file from server to client using tcp


I am trying to send a file from the server to the client and code is running without any errors, but when the client is creating the file I am not getting the required data which is in the file that server is sending.

I looked up for some solutions on StackOverflow itself but couldn't solve my problem as I am new to socket programming can someone tell me where I am going wrong.please help me!!

here are the codes

server.c

// Server side C/C++ program to demonstrate Socket programming
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h> 

#include <netdb.h>
#include <sys/sendfile.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/stat.h>

//#define PORT 8080
int main(int argc, char const *argv[])
{
int fq;

 struct sockaddr_in client,server;
    struct hostent *h;

struct stat st;
int len = 0;
int PORT = strtol(argv[1], NULL, 10);


 char *filename = strdup(argv[2]);




    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    char *hello = "Hello from server";

if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}


    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // Forcefully attaching socket to the port 8080
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
                                                  &opt, sizeof(opt)))
    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );

    // Forcefully attaching socket to the port 8080
    if (bind(server_fd, (struct sockaddr *)&address, 
                                 sizeof(address))<0)
    {
        fprintf(stderr, "%s", "Bind Failed\n");    
            exit(2);
    }
    else {   printf("BindDone: %s\n ", argv[1]);

}


    if (listen(server_fd, 3) < 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }

else {   printf("ListenDone: %s\n ", argv[1]);

}

    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, 
                       (socklen_t*)&addrlen))<0)
    {
        perror("accept");
        exit(EXIT_FAILURE);
    }
///////////////////////////////////////////
    fq = open(filename, O_RDONLY);
    if( fq < 0 )
    {
        fprintf(stderr, "%s", "File error\n");    
            exit(3);
    }

stat(filename,&st);
    len = st.st_size;

    if(sendfile(server_fd,fq,0,len) < 0)
    {
        perror("send error");
        exit(1);
    }

 //   close(sd);





    valread = read( new_socket , buffer, 1024);
    printf("%s\n",buffer );
    send(new_socket , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");

    printf("TransferDone: %s\n ", "bytes\n");

 close(fq);
close(server_fd);
 return 0;
}

client.c

// Client side C/C++ program to demonstrate Socket programming

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#define PORT 8080
#define MAX_LEN 512

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


int rn ;
    struct sockaddr_in address;
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    char *hello = "Hello from client";
    char buffer[MAX_LEN] ;

    FILE *fp;
    int i;
    char *filename = strdup(argv[2]);




if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}



    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Socket creation error \n");
        return -1;
    }

    memset(&serv_addr, '0', sizeof(serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    // Convert IPv4 and IPv6 addresses from text to binary form
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) 
    {
        printf("\nInvalid address/ Address not supported \n");
        return -1;
    }

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        fprintf(stderr, "%s", "Server connection error\n");    
            exit(2);
    }

///////////////////////
fp=fopen( filename, "ab");
    if(fp == NULL)
    {
        fprintf(stderr, "%s", "file not readable\n");    
            exit(3);
    }

////////////////////////

while(1)
    {
        rn=recv(sock,buffer,MAX_LEN,0);

        if(rn < 0)
        {
            printf( "Can 't receive file!\n ");
            exit(1);
        }

        buffer[rn]= '\0 ';

        if(rn != 0)
        {
            fwrite(buffer,1,512,fp);
            bzero(buffer,sizeof(buffer));
        }
        else
        {
            printf("receive over.\n");
            break;
        }
    }



/////////////////////////



    send(sock , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");
    valread = read( sock , buffer, 1024);
    printf("%s\n",buffer );

fclose(fp);
    return 0;
}

Solution

  • Check this:

    server.c

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define PORT 2024
    extern int errno;
    int main (){
      struct sockaddr_in server;
      struct sockaddr_in from;  
      int sd;
      sd = socket (AF_INET, SOCK_STREAM, 0);
      bzero (&server, sizeof (server));
      bzero (&from, sizeof (from));
    
      server.sin_family = AF_INET;  
      server.sin_addr.s_addr = htonl (INADDR_ANY);
      server.sin_port = htons (PORT);
      if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1){
          perror ("bind(). error\n");
          return errno;
      }
      if (listen (sd, 5) == -1){
          perror ("listen(). error\n");
          return errno;
      }
      while (1){
          int client;
          int length = sizeof (from);
          printf ("connect to port :  %d...\n",PORT);
          fflush (stdout);
          client = accept (sd, (struct sockaddr *) &from, &length);
          if (client < 0)
             continue;
          char file[100];
    
          read (client, file, 100) <= 0;
          printf("Filename : %s\n\n", file); 
          //
            FILE *fl = fopen(file, "r");
            char text[500]; //your file size
            int len = 0;
            char c;
    
            while((c = fgetc(fl)) != EOF){
                text[len] = c;
                len++;    
            }
            text[len] = '\0';
            //printf("%d", len);
            //printf("%s", text);
            write(client, &len, 4);
            write(client, text, len);
          close (client);
        }       
    }       
    

    client.c

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <netdb.h>
    #include <string.h>
    extern int errno;
    int port;
    int main (int argc, char *argv[]){
      int sd;   
      struct sockaddr_in server;
    
      if (argc != 3){
          printf ("%s <server_adress> <port>\n", argv[0]);
          return -1;
      }
      port = atoi (argv[2]);
      if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1){
          perror ("socket() error.\n");
          return errno;
      }
      server.sin_family = AF_INET;
      server.sin_addr.s_addr = inet_addr(argv[1]);
      server.sin_port = htons (port);
      if (connect (sd, (struct sockaddr *) &server,sizeof (struct sockaddr)) == -1){
          perror ("connect(). error\n");
          return errno;
      }
      char file[100]; 
      printf("Give me filename: ");
      fflush(stdout);
      scanf("%s", file);
      if (write (sd, file, 100) <= 0)
        {
          perror ("[client]Eroare la write() spre server.\n");
          return errno;
        }
       int len;
       char text[500];
       read(sd, &len, 4);
       read(sd, text, len);
       //printf("%s\n", text);
       FILE *fl = fopen("newFile.txt", "w");
       fprintf(fl, "%s", text);
       fclose(fl);
       close (sd);
    }
    

    Here the client is giving a file name to server, it ( the server ) opens the file and reads all the content from it, sends the data to client who creates a new file and writes data into new created file.

    UPD.

    concurentServer.c

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <errno.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <pthread.h>
    #define PORT 2908
    extern int errno;
    typedef struct thData{
        int idThread; 
        int cl;
    }thData;
    static void *treat(void *); 
    void answer(void *);
    
    int main (){
      struct sockaddr_in server;
      struct sockaddr_in from;  
      int nr;    
      int sd;   
      int pid;
      pthread_t th[100];  
        int i=0;
      if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1){
          perror ("[server]socket().\n");
          return errno;
      }
      int on=1;
      setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
      bzero (&server, sizeof (server));
      bzero (&from, sizeof (from));
        server.sin_family = AF_INET;    
        server.sin_addr.s_addr = htonl (INADDR_ANY);
        server.sin_port = htons (PORT);
      if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1) {
          perror ("[server]bind().\n");
          return errno;
      }
      if (listen (sd, 2) == -1){
          perror ("[server]listen().\n");
          return errno;
      }
      while (1){
          int client;
          thData * td;      
          int length = sizeof (from);
          printf ("[server]Port :  %d...\n",PORT);
          fflush (stdout);
          if ( (client = accept (sd, (struct sockaddr *) &from, &length)) < 0){
                 perror ("[server]accept().\n");
                 continue;
            }
    
           int idThread; 
           int cl; 
        td=(struct thData*)malloc(sizeof(struct thData));   
        td->idThread=i++;
        td->cl=client;
          pthread_create(&th[i], NULL, &treat, td);             
        }
    };
    
    
    static void *treat(void * arg)
    {       
            struct thData tdL; 
            tdL= *((struct thData*)arg);    
            printf ("[thread]- %d - Waiting for message...\n", tdL.idThread);
            fflush (stdout);         
            pthread_detach(pthread_self());     
            answer((struct thData*)arg);
            close ((intptr_t)arg);
            return(NULL);   
    
    };
    
    
    void answer(void *arg){
            char file[100];
              int ap;
            struct thData tdL; 
              tdL= *((struct thData*)arg);
            //
            if (read (tdL.cl, file, 100) <= 0){
                      printf("[Thread number : %d]\n",tdL.idThread);
                  }
              FILE *fl = fopen(file, "r");
            char text[500]; //your file size
            int len = 0;
            char c;
    
            while((c = fgetc(fl)) != EOF){
                text[len] = c;
                len++;    
            }
            text[len] = '\0';
            //printf("%d", len);
            //printf("%s", text);
            write(tdL.cl, &len, 4);
            write(tdL.cl, text, len);
    }