cfilesocketserverstream-socket-client

Why full text from text file is not printing in the server side?


I am using the below code to transfer one text file from client side to server side. I am writing something inside the text file and the stream is getting placed in front of the texts as I am using "r+". But in the server side the full text (newly added text and previous texts which were in the file) is not getting displayed. The server side is only showing the text which been written inside the file. Not sure about the reason. My questions are

  1. Why full text (all the text inside the file including the new text) is not getting displayed in the server side?
  2. How to display the full text?

My server and client code is below: (Only displaying "This is my text". But previously I have written in the file input.txt "This is my program, I want to display the texts written here!". So, it should display "This is my text. This is my program, I want to display the texts written here! ")

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
#define filename "//home//Documents//Example//input.txt"

#define MAX_CLIENTS 5


//the thread function
void *new_connection_handler(void *);

int main(int argc , char *argv[])
{

    //client variables
    int sock;  
    struct sockaddr_in server;
    char buffer[256], server_reply[2000];
    int len;
    
    //server variables
    int socket_desc , client_sock;  
    struct sockaddr_in client;
    socklen_t c = sizeof(client);
    

    //check if the command contain less than two arguments 
    if(argc != 2)
      {
          printf("use either: %s <server/client>\n", argv[0]);
      }
    
    // If the command contains minumum 2 arguments
     else{

    
    // If argv is client then execute the client code
     if(strcmp("client",argv[1]) == 0)
        {
/****************/// Client code here **********************************************************************
          //Create socket
                sock = socket(AF_INET , SOCK_STREAM , 0);
            if (sock == -1)
                {
                printf("Could not create socket");
                }
        puts("Socket created");

        server.sin_addr.s_addr = inet_addr("127.0.0.1");
        server.sin_family = AF_INET;
        server.sin_port = htons( 8888 );

        
        //Connect to remote server
        if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
           {
            perror("connect failed. Error");
            return 1;
           }

        puts("Connected\n");

        
        //keep communicating with server
        /* Time to send the file */

              /******************************************************/
        FILE *pf;
        long int fsize;
        //char str[] = "This is my text.\n";

        //pf = fopen(filename, "r+");
        //fwrite(str , 1 , sizeof(str) , pf );  
          int str=malloc(2000);// update
          strcpy(str,"This is my text.\n");// update
          pf = fopen(filename, "rb");//update
        
        
        if (pf == NULL) 
           {
                printf("File not found!\n");
                return 1;
           }
        else 
           {
                printf("Found file %s\n", filename);

                fseek(pf, 0, SEEK_CUR);
                fsize = ftell(pf);
                rewind(pf);

                printf("File contains %ld bytes!\n", fsize);
                printf("Sending the file now\n");
           }

        while (1) 
           {
                int bytes_read = fread(buffer, 1, sizeof(buffer), pf);
                strcat(str,buffer);// update
                bytes_read=strlen(str);    //update  
                if (bytes_read == 0) // We're done reading from the file
                break;

                if (bytes_read < 0) 
                   {
                    error("ERROR reading from file\n"); 
               }

                while (bytes_read > 0) 
                   {
                    int bytes_written = write(sock, str, bytes_read);// update
                    printf ("bytes_read value %ld\n",bytes_written);
                    bytes_read=bytes_read-bytes_written;
                    //printf ("bytes_read value1 %ld\n",bytes_read);
                    if (bytes_written <= 0) 
                       {
                            error("ERROR writing to socket\n");
                       }
       
                   }    
          }       


        printf("Done Sending the File!\n");
        printf("Now Closing Connection.\n");

        /*********************************************************************************/

        close(sock);

    }
        
    /****************/// Server code here **********************************************************************
        // If argv is server then execute the server code
    if(strcmp("server", argv[1]) == 0 )
        {
            //Create socket
            socket_desc = socket(AF_INET , SOCK_STREAM , 0);
            if (socket_desc == -1)
              {
                printf("Could not create socket");
              }

            //Prepare the sockaddr_in structure
            server.sin_family = AF_INET;
            server.sin_addr.s_addr = INADDR_ANY;
            server.sin_port = htons( 8888 );
            bzero (&server.sin_zero, 8);

            //Bind
            if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
              {
                //print the error message
                perror("bind failed. Error");
                return 1;
              }

            //Listen
            listen(socket_desc , MAX_CLIENTS);

            //Accept and incoming connection
            printf("Waiting for incoming connections\n");

                c = sizeof(client);
            while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, &c)) )
            {
                printf("Connection accepted\n");
                pthread_t thread_id;

                if( pthread_create( &thread_id , NULL ,  new_connection_handler , (void*) (intptr_t)client_sock) < 0)
                  {
                    perror("could not create thread");
                    return 1;
                  }

                printf("Handler assigned\n");
             }


            if (client_sock < 0)
             {
                perror("accept failed");
                return 1;
             }
               } 
         }
    return 0;
}


void *new_connection_handler(void *socket_desc)
{
    //Get the socket descriptor
    int sock = (intptr_t)socket_desc;
    int read_size = 0;
    char client_message[2000];
    int len;
    
   

    
    //Receive a message from client
     while( (read_size = recv(sock , client_message , sizeof(client_message) , 0)) > 0 )
        printf ("Read size %d",read_size);
        printf("Read Text: %.*s", read_size, client_message);

    if(read_size == 0)
    {
        printf("Client disconnected\n");
        fflush(stdout);
    }
    else if(read_size == -1)
    {
        perror("recv failed");
    }
        
   
    return 0;
}

Solution

  • You cannot directly write the content using fwrite() in a file, it overwrite the already exists content.

    You split the operation.

    Read the content from file using fread() and store in the buffer.

    Then you concatenate the buffer with the another buffer.

    char str[]="This is my text.\n";
    

    The above declaration may lead to segmentation fault, when you concatenate with the another string.

    Instead of that you can allocate the memory during runtime with the help of malloc().

    str=malloc(2000);
    

    Allocated memory can be clear using the free() function during runtime.

    Then with the help of strcpy() copy your text to the buffer. You can assign directly after memory allocation.

    strcpy(str,"This is my text.\n");
    

    Now you can use the strcat() to concatenate the readed buffer with the str.

    strcat(str,buffer);
    

    You need to find the length of the concatenated string, use strlen().

    bytes_read=strlen(str);
    

    To access the strcat(),strcpy(),strlen() you need to include the header file string.h

    Now write the str to socket like:

    write(sock, str, bytes_read);
    

    If you use the step it will work fine.

    UPDATE:

    int str=malloc(2000);
    

    instead of that use:

    char *str=malloc(2000);
    
    strcat(str,buffer);// update            
    bytes_read=strlen(str);    //update
    

    Instead of that two line use the below line in strcat function like

    if(bytes_read != 0)
    { 
        strcat(str,buffer);// update            
        bytes_read=strlen(str);    //update
    }
    

    In thread function change the printf to

    printf("Read Text: %s", client_message); 
    

    If you made the above change the program will work as you expected.