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
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;
}
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.